Handler原理机制解析,Android开发中的重要性

Handler在android程序开发中使用的非常频繁、我们知道android是不允许在子线程中更新UI的,这就需要借助Handler来实现,那么你是否想过为什么一定要这个这样子做呢?而且Handler的内部消息处理机制究竟是什么样的呢?Handler的原理是需要通过源代码才能说的清楚的,而且它处理机制比较复杂。

Handler主要用于异步消息的处理:当发出一个消息之后,首先进入一个消息队列,发送消息的函数即刻返回,而另外一个部分在消息队列中逐一将消息取出,然后对消息进行处理,也就是发送消息和接收消息不是同步的处理。 这种机制通常用来处理相对耗时比较长的操作。

Handler的工作流程

Handler原理机制解析,Android开发中的重要性_第1张图片

添加图片注释,不超过 140 字(可选)

Looper就像传送带传送消息,handler通过send/post方法,将货物送上传送带,这些货物就是message,排成messageQueue。当Looper.loop()调用,就是给传送带插上了电,无休止地转动,当传送到那一头了,就通过handler.dispatch()方法传递给需要货物的地方。

原理

简单概括一下:

Handler创建时会采用当前线程的Looper来构建内部的消息循环系统如果当前线程没有Looper那么就会报错,因此使用时主要为当前线程创建Looper即可或者在一个有Looper的线程中创建Handler也可以,在我们的UI线程中系统已经在一开始就为我们创建好了,自定义的子线程如何创建后面会说。

首先需要搞定几个概念

【MessageQueue】是一种数据结构,见名知义,就是一个消息队列(注意不是数据结构的队列,其实是个单链表),存放消息的地方。每一个线程最多只可以拥有一个MessageQueue数据结构。创建一个线程的时候,并不会自动创建其MessageQueue。通常使用一个Looper对象对该线程的MessageQueue进行管理。主线程创建时,会创建一个默认的Looper对象,而Looper对象的创建,将自动创建一个Message Queue。其他非主线程,不会自动创建Looper,要需要的时候,通过调用prepare函数来实现。

示例:

[java]  view plain  copy
public void run(){   
          Looper.prepare(); //创建该线程的Looper对象  
 //这里Looper.myLooper()获得的就是该线程的Looper对象了  
          handler = new ThreadHandler(Looper.myLooper());   
          Message msg = handler.obtainMessage(1,1,1,"我自己");   
          handler.sendMessage(msg);        
          Looper.loop();  
 
      }   

俩行代码,该线程就具有自己的Looper啦

【Message】消息对象

MessageQueue里面可以存放Message的消息一个Message Queue中包含多个Message。Message实例对象的取得,通常使用Message类里的静态方法obtain(),该方法有多个重载版本可供选择;它的创建并不一定是直接创建一个新的实例,而是先从Message Pool(消息池)中看有没有可用的Message实例,存在则直接取出返回这个实例。

[java]  view plain  copy


/** 
     * Return a new Message instance from the global pool. Allows us to 
     * avoid allocating new objects in many cases. 
     */ 
 public static Message obtain() {  
 synchronized (sPoolSync) {  
 if (sPool != null) {  
                Message m = sPool;  
                sPool = m.next;  
                m.next = null;  
                m.flags = 0; // clear in-use flag 
                sPoolSize--;  
 return m;  
            }  
        }  
 return new Message();  
    }  

源码中可以看出如果Message Pool中没有可用的Message实例(poolsize=50),则才用给定的参数创建一个Message对象。调用removeMessages()时,将Message从Message Queue中删除,同时放入到Message Pool中。除了上面这种方式,也可以通过Handler对象的obtainMessage()获取一个Message实例。

通常Message Queue只有俩种单链表操作 插入(对应方法enqueueMessage)和读取(next)

【Looper】

是MessageQueue的管理者。每一个MessageQueue都不能脱离Looper而存在,Looper对象的创建是通过prepare函数来实现的。同时每一个Looper对象和一个线程关联。通过调用Looper.myLooper()可以获得当前线程的Looper对象创建一个Looper对象时,会同时创建一个MessageQueue对象。除了主线程有默认的Looper,其他线程默认是没有MessageQueue对象的,所以,不能接受Message。如需要接受,自己定义一个Looper对象(通过prepare函数),这样该线程就有了自己的Looper对象和MessageQueue数据结构了。Looper从MessageQueue中取出Message然后,交由Handler的handleMessage进行处理。处理完成后,调用Message.recycle()将其放入Message Pool中。

Looper扮演着消息循环角色,一有消息就处理,否则就阻塞在那里。

本文主要是对在Android开发中,Handler的原理机制的解析。Handler在Android开发中处于非常重要的技术之一。更多有关Handler的技术或者高级Android开发,可以参考《Android核心开发手册》点击可以查看详细类目。

Handler原理机制解析,Android开发中的重要性_第2张图片

你可能感兴趣的:(android开发,android,Android开发,程序员开发,Android面试,程序员,handler)