Android 异步消息处理机制 让你理解 Looper、Handler、Message三者关系

一:Handler消息机制

为什么要有Android消息机制?

我们知道Handler的主要作用是将一个任务切换到某个指定的线程去执行,比如Android规定访问UI只能在主线程中进行,如果在子线程中访问那么程序会抛异常,如下所示:

void checkThread(){
        if(mThread != Thread.currentThread()){  
            throw new CalledFromWrongThreadException(  
                "Only the original thread that created a view hierarchy can touch its views.");  
        }  
    }


这个时候就需要通过Handler来把这个任务从子线程切换到主线程中来执行,这样程序就不会抛异常。

为什么系统不允许在子线程中访问UI呢?

     这是因为Android的UI控件的线程是不安全的,如果在多线程中访问UI控件则会导致不可预期的状态。

那为什么不对UI控件访问加锁呢?

      缺点有两个:首先加锁会让UI控件的访问的逻辑变的复杂;其次,锁机制会降低UI的访问效率。那我们不用线程来操作不就行了吗?但这是不可能的,因为Android的主线程不能执行耗时操作,否则会出现ANR。所以,从各方面来说,Android消息机制是为了解决在子线程中无法访问UI的矛盾。

   

消息机制概述

    Android通过Looper、Handler,Message,MessageQueue来实现消息循环机制。Android的消息循环是针对线程的,每个线程都可以有自己的消息队列和消息循环。

Android系统中的Looper负责管理线程的消息队列和消息循环。通过Loop.loop()方法后,就会进去一个无限循环中,不断地轮循消息队列,并把Message传递到Handler的handleMessage()中。

前面提到,Android的消息队列和消息循环都是针对具体线程的,一个线程可以存在一个消息队列MessageQueue和轮循者Looper主线程默认存在Looper和MessageQueue,但是创建的工作线程默认是没有消息队列和轮循者的,如果想让工作线程具有消息队列和消息循环,就需要在线程中先调用Looper.prepare()来创建消息队列,然后调用Looper.loop()进入消息循环

Android的消息机制的总体流程就是:

  Handler向MessageQueue发送一条消息(即插入一条消息),MessageQueue通过next方法把消息传给Looper,Looper收到消息后开始处理,然后最终交给Handler自己去处理。换句话说就是:Handler给自己发送了一条消息,然后自己的handleMessage方法处理消息,只是中间过程经过了MessageQueue和Looper。调用的方法过程如下:Handler.sendMessage方法–>Handler.enqueueMessage–>MessageQueue.next–>Looper.loop–>handler.dispatchMessage–>Handler.handleMessage(或者Runnable的run方法或者Callback.handleMessage)。

下面是我们创建的工作线程:

class WorkThread extends Thread {
   	 public Handler mHandler;
	 public void run() {
	//创建消息队列
         Looper.prepare();
         
	mHandler = new Handler() {
         public void handleMessage(Message msg) {
             	   // 处理收到的消息
			
           	 }
        };
	//开始轮循消息队列
        Looper.loop();
    }
}

附上自己画的Handler消息机制实现图

猜你喜欢

转载自blog.csdn.net/qq_34927117/article/details/53220512