android Why not allow open a new thread to update the UI, but with the handler to update the interface

Here's a quick way to create a new thread:

The first: a child thread directly create and start
      new new the Thread () {
@Override
public void RUN () {
     // work written in the child thread needs to be done here
        }
   } .start ();
   
second: create child threads, then start
        private thread newThread; // declare a child thread
newthread the thread new new = (the Runnable new new () {
    @Override
            public void RUN () {
            // write here child thread to be done
            }
        });

    newThread.start (); // start the thread

 

Operation is likely to be complicated by, and only one interface
this is one thing and buy a ticket queuing
for tickets too many people, there is only one ticket, and only one by one
if you open multiple threads, so 100 people at the same time to buy tickets, and do not line up, then the consequences will happen - -
Similarly, you open multiple threads, 100 threads to make the display settings with a TextView content of each display content is different, it is who to listen to?

So why not direct new a new thread but to use a so-called handler?

Because of a new sub-thread handler before use, and
otherwise update UI handler to do in the main thread? Superfluous

like only one person to buy a ticket, the ticket will do with him, he said: Comrades, please line up! ?
handle is the main thread, Thread from the thread. Control data changes only in the main thread, so use the handle

Update the UI only in the main thread, otherwise it will error. But sometimes we need to update the operating UI, handler will debut in the child thread, which can handle data to the main thread of the thread, the main thread synchronization to update the UI.

First look at an example of this

 Package Comkhua;

import android.app.Activity;
import android.os.Bundle;

public class UpdateUInum1Activity extends Activity {
 
 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
  new Thread(new Runnable() {
   @Override
   public void run() {
    setTitle("fengyi.hua");
   }
  });
 }
}

    In order to achieve the above is to be updated by a Thread Title, can achieve this function, refresh the UI interface. But this is wrong because it violates the single-threaded model: Android UI is not thread-safe operations and these operations must be performed in the UI thread.

    Some people find this method really quite superfluous, why, because since it is refreshed once, I can perform the operation of the refresh Title in the main thread, why open thread. This is because it may involve delays or other. For example, after waiting 1min refresh operation, this time to ensure that the main UI thread is operational, so use the Thread updated. But it does have a conflict for single-threaded model of android is not recommended. Examples of the use of the following errors:

 

Package Comkhua;

import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;

public class UpdateTitleActivity extends Activity {
 

  private void updateTitle() {
  Date date = new Date();
  int hour, minute, second;
  String shour, sminute, ssecond;
  hour = (date.getHours() + 8) % 24;
  minute = date.getMinutes();
  second = date.getSeconds();

  if (hour < 10) {
   shour = "0" + hour;
  } else {
   shour = "" + hour;
  }

  if (minute < 10) {
   sminute = "0" + minute;
  } else {
   sminute = "" + minute;
  }

  if (second < 10) {
   ssecond = "0" + second;
  } else {
   ssecond = "" + second;
  }

  setTitle ( "Current Time:" + shour + ":" + sminute + ":" + ssecond);
 }

 @Override
 public void the onCreate (the Bundle savedInstanceState) {
  super.onCreate (savedInstanceState);
  the setContentView (R.layout.main);
  the Timer Timer new new = the Timer ();
  timer.scheduleAtFixedRate (new new myTask (),. 1, 1000); // here is the use of Timer, with the use of Thread is a result. which performed

  // effect is updated several times Title, will not see a problem.
 }

 private class myTask extends TimerTask {
  @Override
  public void run() {
     updateTitle();
  }

 }

}

   The above code is used to refresh every 1s Title, to display the current time. However, because android is a single-threaded model, there is a security thread, so when the second refresh of error.

 

 

The correct approach

    The above two methods, namely Thread method, and TimerTask methods. Is commonly used in Java, because the thread-safe. But in the android single-threaded model, it can not be used. There are two correct way.

 

1.Thread+handler

2.TimerTask + Trades

3.Runnable+Handler.postDelayed(runnable,time)

 

Examples: Timertask + handler

Package Comkhua;

import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;

public class UpdateTitleActivity extends Activity {
 

  private Handler mHandler = new Handler(){

  @Override
  public void handleMessage(Message msg) {
  super.handleMessage(msg);
  switch (msg.what) {
  case 1:
  updateTitle();
  break;
 
  default:
  break;
  }
  }
  };

 private void updateTitle() {
  Date date = new Date();
  int hour, minute, second;
  String shour, sminute, ssecond;
  hour = (date.getHours() + 8) % 24;
  minute = date.getMinutes();
  second = date.getSeconds();

  if (hour < 10) {
   shour = "0" + hour;
  } else {
   shour = "" + hour;
  }

  if (minute < 10) {
   sminute = "0" + minute;
  } else {
   sminute = "" + minute;
  }

  if (second < 10) {
   ssecond = "0" + second;
  } else {
   ssecond = "" + second;
  }

  setTitle ( "Current Time:" + shour + ":" + sminute + ":" + ssecond);
 }

 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
  Timer timer = new Timer();
  timer.scheduleAtFixedRate(new myTask(), 1, 10000);
 }

 private class myTask extends TimerTask {
  @Override
  public void run() {
    Message msg = new Message();
    msg.what = 1;
    mHandler.sendMessage(msg);
  }

 }

}

 

    Remember that, in the process handleMessage which are, of course, may not be within the class methods handleMessage inside the Callback handler. Callback Handler also with its knowledge, can speak later.

 

 

In order to solve this problem in Android UI update non-UI thread, Android provides a number of methods from other threads to access the UI thread.

  1. Activity.runOnUiThread(Runnable)
  2. View.post(Runnable)
  3. View.postDelayed(Runnable, long)
  4. Looper way.
  5. Use Handler way.
// 1. 使用runOnUiThread的方式
runOnUiThread(new Runnable() { @Override public void run() { Toast.makeText(MainActivity.this, "sdf", Toast.LENGTH_SHORT).show(); } }); // 2. 使用post的方式 btn.post(new Runnable() { @Override public void run() { Toast.makeText(MainActivity.this, "sdf", Toast.LENGTH_SHORT).show(); } }); // 3. 使用postDelayed的方式 btn.postDelayed(new Runnable() { @Override public void run() { Toast.makeText(MainActivity.this, "sdf", Toast.LENGTH_SHORT).show(); } }, 1000); // 4. 使用Looper的方式 Looper.prepare(); Toast.makeText(MainActivity.this, "sdf", Toast.LENGTH_SHORT).show(); Looper.loop(); // 5. 使用Handler的方式 private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case 1: Toast.makeText(MainActivity.this, "sdf", Toast.LENGTH_SHORT).show(); break; } } }; // 发送消息 handler.sendEmptyMessage(1); 或者 Handler handler = new Handler(Looper.getMainLooper()); handler.post(new Runnable() { @Override public void run() { Toast.makeText(MainActivity.this, "sdf", Toast.LENGTH_SHORT).show(); } });

Guess you like

Origin www.cnblogs.com/Alex80/p/11563797.html