Handler basic use

Summary: Handler processing mainly for the message, the core class Android SDK to handle asynchronous message, the main thread and the child thread to communicate via a Handler, sub-thread can notify the main thread UI updates by Handler.

Section

Use Handler achieve异步更新UI
1. Create Handler

Handler handler=new Handler(){
    @Override
    public void handleMessage(Message msg){
       super.handleMessage(msg);
         //收到消息后,将会调用此方法
         //可以在这里进行UI更新操作
       }
   };

2. Then just send an empty message in a child thread to

new Thread(new Runnable(){
        @Override
        public void run(){
           handler.sendEmptyMessage(1);
        }
   }).start();

Ha ha ha, then realized the asynchronous update UI, is not that simple ah! But still the main thread to update the UI, and the role Handler is essentially to notify the main thread to
update the UI, because Android是单线程模式, so we 不能在子线程更新UIcan only notify the main thread to update the UI by Handler.

So the question is, if we sent a message in multiple places, and every place have to be different UI update operation, so we have to how to distinguish it? Ha ha ha ... In fact, we are nothing to worry about this, because in fact Handler long as we take into account, do not believe, we Stepping back even look!

From here, we can see that here also carries a parameter "1" and this 1is the message of this article 标识, it can be understood as this message id, by which we will be able to distinguish between news!

handler.sendEmptyMessage(1);

Then ... create Handler became so

Handler handler=new Handler(){
    @Override
    public void handleMessage(Message msg){
       super.handleMessage(msg);
          switch(msg.what){
             case 1:
              {
                 //收到标识为1的消息后,将会调用这里
                 //可以在这里进行UI更新操作
              }
          }
       }
   };

Expansion: If you think only send a blank message Handler, then you are wrong, because Handler还支持发送一个Message对象, though it! Before looking at the code, or take a look at this!

parameter Resolve
arg1 Parameter is an int type, int type can pass a message
arg2 Like arg1
obj The relatively stronger, the parameter is an Object type, Object type can pass a message.
what A message identifier, can be understood as a message id, mainly used to distinguish the message.

Send a Message object
Message对象是可以带参数的 , parameters have been parsed, and here do not explain, ha ha ha ...

Message message =new Message();
message.arg1=1;
message.arg2=2;
message.what=3;
message.obj="测试";
handler.sendMessage(message);

Ha ha ha, how about it! Is not feeling a lot of tall moment of it, there is no feeling ah? Ha ha ha ... then Handler code becomes so.

Handler handler=new Handler(){
    @Override
    public void handleMessage(Message msg)
    {
       super.handleMessage(msg);
          switch (msg.what){
             case 1:
              {
                 //收到标识为1的消息后,将会调用这里
                 //可以在这里进行UI更新操作	
              }
             break;
             case 3:
              {
             //收到标识为3的消息后,将会调用这里
                Log.d("arg1", msg.arg1 + "");
                Log.d("arg2", msg.arg2 + "");
                Log.d("obj", msg.obj + "");
              }
          }
       }
   };

Running about.

Message Optimization: 官方建议We will

Message msg =new Message();

Changed

Message msg = handler.obtainMessage();

or

Message msg = Message.obtain();

Pros: In this case, may be responsible for the system to create and destroy objects message

further study

Section II

Careful friends may notice Handler object has a postmethod for transmitting a Runnable object, we need this Runnable object, override the run () method.

It should be noted here is: send Runnable object using post 虽然看起来像是在子线程中执行,但其实它是在主线程中执行的! Because every time we deal with the child thread will Runnable contact with, it's easy to mistake Runnable is the child thread, but in fact can create a child thread is only one, and that is Thread this case you should get the point! This is entirely possible by Log output current thread, validate, do not believe you can try.

Because use post发送的消息不会被Handler对象接收, so there need to take note, do not put them two mixed up, all operations are just trying to be difficult to write in the Runnable object.

General usage:

new Thread(new Runnable(){
     @Override
     public void run()
     {
        handler.post(new Runnable()
        {
          @Override
           public void run()
            {
               //UI更新操作
               //这里的所有操作都会在主线程中执行
            }
        });
      }
   }).start();

Of course, you can also write

private class myRunnable implements Runnable{
    @Override
    public void run()
    {
       // UI更新操作
       // 这里的所有操作都会在主线程中执行
    }
 }

then…

myRunnable myRunnable=new myRunnable();
handler.post(myRunnable);

Of course, you can also do a good job related operations when creating Handler, then you just send out a message to where you want to call.

Ah na ... Hadler basic usage of these, and now rush to try it! Ha ha ha ...

further study

Section III:

HandlerThread

If we want to perform some of the more time-consuming operation Handler object, we usually think of it thrown in the sub-thread to execute, so a new direct child thread directly Handler does not get away with it? I think most people are probably react like this, right!

Handler Handler=new Handler(){
    @Override
    public void handleMessage(Message msg){
       super.handleMessage(msg);
       new Thread(new Runnable(){
          @Override
          public void run(){
             //在这里执行耗时操作
          }
       }).start();
    }
 };

Ah na, so does implement asynchronous execution, but if this Handler object receives a message a lot of it? So what will happen?

To make the effect more obvious, I wrote in a log Handler object in the output data of the output of the current thread, and sent three messages to it, the results are as follows:

Also, I did the same operation Looper thread, the results are as follows:

analysis:

phenomenon in conclusion
Handler ordinary objects to create three threads Each receives a message, it will create a new thread, this method is a great thread overhead, it is not recommended.
Only one thread Looper thread No matter how many messages are received, it will only create a thread

So now you should know the role Looper thread of it!

Note: This is mainly want to tell you what is Looper thread, not a call to go write. Officials have a good package Looper thread, called HandlerThread, this ... behind us revisit.

But before learning Looper thread, or is this first look at it!

Meaning of a word Explanation
Looper A thread can only have a Looper, a Looper can only have a MessageQueue, Looper responsible for circulating the message, it would have been taken out MessageQueue Message from the inside, and handed over to the appropriate Handler for processing.
MessageQueue Message queue for storing messages sent by the Handler
Message Message body, for loading the object need to be transmitted, stored in the MessageQueue
Handler ... I think ... this has not introduced it!

Looper thread

If we want to use the Handler in the child thread, we also need to create a Looper thread object inside, it allows messages to be circulated.

Looper线程其实就是一个拥有Looper的子线程

So the question is, why do we use Handler in the main thread, the objects do not create Looper? Because 主线程默认是创建Looper对象的, so we do not need to go create.

Creating Looper thread

Specific code as follows:

private class myThread extends Thread{
    public Handler Handler;
    @Override
    public void run()
    {
       Looper.prepare();
       Handler = new Handler(){
          @Override
          public void handleMessage(Message msg)				{
             super.handleMessage(msg);
             Log.d("测试2", Thread.currentThread() + "");
             //异步任务
             //可执行一些比较耗时的操作
             //不能执行UI更新操作
             }
          };
          Looper.loop();
       }	
   }

Some of the above method and using different
specific look Code:

Exemplified: Send a message to the sub-thread

myThread myThread=new myThread();
myThread.start();
try
{
myThread.sleep(500);
}
catch (InterruptedException e)
myThread.Handler.sendEmptyMessage(0);

Running about.

By contrast, we can clearly see that 它是在子线程里面执行的,所以不能执行UI更新操作,可用于一些比较耗时的操作.

Test 1, I wrote on the inside of the main thread of Handler objects, the output is the current thread, just to do some comparison.

Handler handler=new Handler(){
   @Override
   public void handleMessage(Message msg)
   {
      super.handleMessage(msg);
      Log.d("测试1", Thread.currentThread() + "");
      //UI更新操作
      }
   };
handler.sendEmptyMessage(0);

Continue to learn Looper thread

After understanding the above things. We are now in the main thread to create a Handler object, and the object is to specify a Looper it, put it designated as a target Looper Looper thread of it!

Specific implementation steps are as follows:

private class myThread extends Thread{
    public Looper looper;
    @Override
    public void run()
    {
       looper.prepare();
       looper=looper.myLooper();
       looper.loop();
      }
   }

Here to explain the above
Looper.myLooper();
to get the current thread Looper objects

Remember to write on the Activity of onDestroy the
myThread.looper.quit();
termination Looper Looper cycle for threads

Looper then specify the object when the main thread to create Handler objects

myThread myThread=new myThread();
myThread.start();
Handler handler=new Handler(myThread.looper){
    @Override
    public void handleMessage(Message msg)
    {
       super.handleMessage(msg);
       Log.d("嘿嘿",Thread.currentThread()+"");
       //异步任务
       //可执行一些比较耗时的操作
       //不能执行UI更新操作
   }
 };
 handler.sendEmptyMessage(1);

then. . .

程序崩溃了

Why is this?
By running log, we can see
myThread.looper

Here there was a null value problem, because when we create a program Handler object, Looper target child thread has not had time to create, so that led to the collapse of the program, then we should go to how to solve it?

Solution:

After starting Looper thread, let the main thread to sleep 500ms, go create Handler object. This would solve the problem of null values.

myThread myThread=new myThread();
myThread.start();
try
{
Thread.sleep(500);
}catch (InterruptedException e){}
Handler handler=new Handler(myThread.looper){
    @Override
    public void handleMessage(Message msg){
       super.handleMessage(msg);
       //异步任务
       //可执行一些比较耗时的操作
       //不能执行UI更新操作
    }
 };
 Message msg= Message.obtain();
 handler.sendMessage(msg);

or

myThread myThread=new myThread();
myThread.start();
try{
myThread.sleep(500);
}
catch (InterruptedException e){}
Handler handler=new Handler(myThread.looper){
    @Override
    public void handleMessage(Message msg){
       super.handleMessage(msg);
       //异步任务
       //可执行一些比较耗时的操作
       //不能执行UI更新操作
    }
 };
 Message msg= Message.obtain();
 handler.sendMessage(msg);

At this time, we output a log Handler object, the contents of the current thread, we'll see它输出的是子线程,而不是主线程

So, we write in the main thread Handler also has successfully achieved asynchronous execution, and then 可以在里面执行一些比较耗时的操作, because it is performed in the sub-thread, so we are 不能执行UI更新操作.

In fact, before writing here and a Handler object in the child thread is the same, but nothing to write separately.

Google官方We do not recommend to go your own custom Looper thread, we recommend direct use already packaged Looper thread HandlerThread, multi-thread concurrency can solve the problem for us, but also simple and easy to use.

HandlerThread是什么?
I believe you should now know what the HandlerThread is, in fact, Googler HandlerThread official package Looper thread can perform some of the more time-consuming operation, the same, the UI update operations can not be performed, then in the end we want to HandlerThread how to use it? please look below:

HandlerThread use:

HandlerThread HandlerThread=new HandlerThread("这个随便写");
HandlerThread.start();
Handler handler=new Handler(HandlerThread.getLooper()){
   @Override
   public void handleMessage(Message msg){
      super.handleMessage(msg);
      Log.d("嘿嘿",Thread.currentThread()+"");
      //异步任务
      //可执行一些比较耗时的操作
      //不能执行UI更新操作
      }
 };
 handler.sendEmptyMessage(1);

Run it:

how about it? You learn it? Use HandlerThread is very simple.

Write blog is really easy! It is the heart Lei Ya! But also deepened my understanding of the Handler, so no loss ... ha ha ha.

This article to end here

Hope everyone likes it.

Guess you like

Origin blog.csdn.net/weixin_45263548/article/details/92783103
Recommended