Android: Handler asynchronous processing of applications + Thread

Worried about the disappearance of the original, to do this record, thanks

https://www.cnblogs.com/net168/p/4075126.html

 

Foreword

  A long time ago I heard, and every android application that will run separately in a separate virtual machine dalvik process, but will run a primary UI thread (Main Thread) in each virtual machine to start, and why I called the main UI thread instead of the main thread AI or BI main thread of it? Because it has to deal with all the events and UI related; because the Android UI system uses a single-threaded model, it can only be carried out by the main thread UI UI operations on them if the child thread holding many hands make light of consciousness to help the main UI thread updates UI interface, then I'm sorry oh ~ Android system will be incorrect report. Say vulgar point is this: we can only ravaged UI UI interface by the main thread, but other thread, then the defendant will Gongsui female dry drops. .

  So now the question is! Given the recent fire excavator so, I am sorry to continue to ask this question. . . Huh ~ network operations such as time-consuming operation excavators as we did when downloading files with excavator to dig a pit, like take some time; when the driver of an excavator dug a pit boss feedback to find work complete, we naturally want to download a file good immediately told to wait before the screen hard to force users, who know what they want to see how worried ** avi it; but when you dig nerve to call the boss to see you next to it? Boss every minute for the tens of millions down to do it - so busy Well Similarly, for network operations, we certainly can not operate a network in the main UI thread, as this will block the main thread cause death card interface, can also cause ANR (application no response). We should file downloading, file reads like a time-consuming operation to be placed in the sub-thread, until the child thread notifies the UI interface responds completion time-consuming operation.

Do not consuming operations in the main UI thread

  If you do nothing and be sure to download the files in the main UI thread, time-consuming operation to load large files and the like. The following code:

Private the Button BTN;
 // lifecycle onCreate such a method is to allow the main UI thread 
@Override
 protected  void onCreate (the Bundle savedInstanceState) {
  Super .onCreate (savedInstanceState); 
  the setContentView (R.layout.activity_main); 
        
  BTN = ( the Button) the findViewById (R.id.btn); 
        
  btn.setOnClickListener ( new new OnClickListener to () { 
    @Override 
    public  void the onClick (View V) { 
      DOWNLOAD (); // call the function to download the main UI thread 
    } 
  }); 
} 
    
Private  void DOWNLOAD () {
  the try { 
    the Thread.sleep (10000); // Sleep 10 seconds, the analog network file download consuming operations 
  } the catch (InterruptedException E) { 
    e.printStackTrace (); 
  } 
}

You will find the main interface card 10 seconds :( simulation button to download the operation of a dark, indicating that the button has been pressed)

When you run your hand is uncontrollable, even though a few clicks interface, all right ~ Androi system will immediately send you a gift ANR Oh, and also not 998 yuan yeah!

Summary A: Do not be time-consuming operation in the main UI thread, you might question what is the main UI thread, the main thread main UI is running Activity, Service, etc. inside the life-cycle approach, so do life-cycle approach in such onCreate ( ) to download these great events. For the time-consuming operation, we should create a new child thread and at his disposal, but also need to pay attention to that.

Do not update the UI interface in the sub-thread

  Since we say download the file to be in the child thread, then we create a new sub-thread to download into operation carried out inside slightly, as follows:

protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
        
  btn = (Button) findViewById(R.id.btn);
  text = (TextView) findViewById(R.id.text);
        
  btn.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
      new Thread(){
        @Override
        public void run() {
          //在子线程中进行下载操作
          try {
            Thread.sleep(10000);//Sleep 10 seconds, the analog consuming operations 
          } the catch (InterruptedException E) { 
            e.printStackTrace (); 
          } 
          text.setText ( "download completed"); // Set the TextView, download completion notification UI interface 
        } 
      } .start (); 
    } 
  }); 
}

After 10 seconds, you'll feel perfectly displayed in the UI interface "download is complete," What? Generally, the emergence of this system is consistent with Androi consistent style

And Log being given as follows

In fact, it is the younger brother of English scrap wood, but it was vague told me: This is not a call can only update the UI in the main thread do? Do not believe, look off to Kingsoft translation. . . .

Summary A: Do not update the UI interface in the sub-thread, this will lead to android system error, application crashes exit. Single-threaded mode, we can only through the UI interface UI of the main thread to the UI interface related updates, do not cross the line work, you have to remember is ~ UI interface is the wife of the main UI thread, you these sub thread no one even think about moving!

Thread + Handler using asynchronous processing

  Can not be performed when the main thread so the question is, now we need to carry out time-consuming operations (such as downloading files), we need to inform the user in the UI interface we can not finish the job the sub-thread execution. This seems to be a hot potato it tricky, but fortunately Google provides us with a save us Handler in distress, and a main thread can make stuff to listen to the child thread to send the message, as the realization of the principle Handler I'll be back the article details, and now we just need to first understand Handler usage.

private Button btn;
private TextView text;
    
private Handler handler = new Handler(){
  private int process = 0;
  @Override
  public void handleMessage(Message msg) {
    switch(msg.what){
    case 0://更细下载进度
      process += 1;
      text.setText("下载" + process + "%");//在主线程中更新UI界面
      break;
    case 1://提示下载完成
      text.setText("下载完成");//在主线程中更新UI界面
      break;
    default:
      break;
    }
  }
};
//onCreate之类的生命周期的方法就是允许在UI主线程中
@Override
protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
        
  btn = (Button) findViewById(R.id.btn);
  text = (TextView) findViewById(R.id.text);
        
  btn.setOnClickListener(new OnClickListener() {
  @Override
  public void onClick(View v) {
    new Thread(){
      @Override
      public void run() {
        //在子线程中进行下载操作
        for(int i = 0; i < 100; i++){
          try {
            Thread.sleep(200);//休眠0.2秒,模拟耗时操作
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
          handler.sendEmptyMessage(0);//发送消息到handler,通知下载进度
        }
        handler.sendEmptyMessage(1);//发送消失到handler,通知主线程下载完成
        }
      }.start();
    }
  });
}

这里来解释一下Handler的使用方法:

1、我们为了不阻塞主线程,将下载任务通过子线程来执行。

new Thread(){
  @Override
  public void run() {
    //在子线程中进行下载操作
    for(int i = 0; i < 100; i++){
      try {
        Thread.sleep(200);//休眠0.2秒,模拟耗时操作
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
      handler.sendEmptyMessage(0);//发送消息到handler,通知下载进度
    }
    handler.sendEmptyMessage(1);//发送消失到handler,通知主线程下载完成
  }
}.start();

2、当子线程需要跟主线程交流时,也就是当子线程要跟UI主线程说:亲,偶下载文件到80%了或者偶已经把文件下载完成了!执行这句代码

handler.sendEmptyMessage(1);//发送消失到handler,通知主线程下载完成

3、当发送空消息之后,在Handler将会收到子线程发来的消息,触发回调方法handlerMessage(),我们就在这里对UI界面进行更新,这个回调方法是运行在UI主线程的

@Override
public void handleMessage(Message msg) {
  switch(msg.what){
  case 0://更细下载进度
    process += 1;
    text.setText("下载" + process + "%");//在主线程中更新UI界面
    break;
  case 1://提示下载完成
    text.setText("下载完成");//在主线程中更新UI界面
    break;
  default:
    break;
  }
}

4、最后,UI界面更新成功!(图嘛,我这里就不上了。。。。)

小结一个:对于比较耗时间的任务,我们一般需要放在子线程中执行;当子线程更新UI界面时,子线程可以通过Handler来通知主线程更新,一般通过发送消息来触发handlerMessage()这个回调方法来执行UI界面的更新。

进一步简略de操作:handler.post方法和view.post方法

  但是如果你觉得每次都要重写handlerMessage()比较麻烦,我们完全可以用更加简略的方法来解决我们的需求,就是用handler中的post方法。代码如下

 

new Thread(){
  @Override
  public void run() {
    //在子线程中进行下载操作
    try {
      Thread.sleep(1000);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
    handler.post(new Runnable() {
      @Override
      public void run() {
        text.setText("下载完成");
      }
    });//发送消失到handler,通知主线程下载完成
  }
}.start();

 

这样处理的话我们就可以不用重写handlerMessage()方法了,适合子线程与主线程进行较为单一的交流。但在这里我们要强调的一点的是,post里面的Runnable还是在UI主线程中运行的,而不会另外开启线程运行,千万不要在Runnable的run()里面进行耗时任务,不然到时又ANR了可别找我哦。。 如果你有时候连handler都不想搞,还可以这样写代码滴。 我们只需要把handler换成View组件进行post,更新任务自然会加载到UI主线程中进行处理。

text.post(new Runnable() {
  @Override
  public void run() {
    text.setText("下载完成");
  }
});//发送消失到handler,通知主线程下载完成

至于Handler机制以及这两种post的原理,我将会在后面的博客文章中专题介绍,这里只提供一个使用方法而已。

 

Guess you like

Origin www.cnblogs.com/zonglonglong/p/11258399.html