Learn From Android Source Code之异步消息处理线程

来源:互联网 发布:app视频录像软件 编辑:程序博客网 时间:2024/05/20 23:04

这里所说的异步消息处理线程不要和跨进程调用(IPC)混淆,看到Handler对象,就应该想到异步处理线程。

对于普通线程而言,执行完run()方法内的代码后线程就结束。而异步处理线程是指,线程启动后会进入一个无限循环体之中,每循环一次,从其内部取出一个消息,并回调相应的消息处理函数,执行完一个消息后继续循环,如果消息队列为空,线程会暂停,知道出现新消息。

其实本质还是一个线程。以下为实现异步线程一般思路:

在android中实现异步线程的思路:


线程内部有一个或者多个Handler对象,外部程序通过Handler对象向线程发送异步消息,消息经过handler传到MQ对象中,线程内部只能有一个MQ对象,线程从MQ中读取消息,并回调该handler对象中的回调函数handleMessage()。

1.Looper

两点作用:第一,为调用该类中静态函数prepare()的线程创建一个MQ

    第二,提供静态函数loop(),使调用该函数的线程进行无限循环,并从MQ中读取消息

代码如下:

Looper的构造函数中会创建一个MQ对象。当我们需要把一个线程变为异步消息处理线程的时候,应该在thread类的run()中用Looper.prepare()为该线程创建一个MQ对象,然后调用Looper.loop()是当前线程进入消息处理循环。Loop()代码如下:

该段代码执行流程:

1.调用myLooper()返回当前线程的Looper对象,该函数内部通过调用sThreadLocal.get()来返回当前线程id对应的Looper对象

2.进入while(true)无限循环。

(1)调用MQ对象的next()函数取出队列中的消息。注意,如果当前队列为空,则线程会被挂起,即next()函数内部会暂停该线程 。

(2)回调msg.target.dispatchMessage()函数,完成对该消息的处理。msg.target的类型是Handler。消息的具体处理是由程序指定的。

(3)消息处理完,调用msg.recycle()回收message对象占用的系统资源

2.MQ

消息队列采用排队方式进行消息处理,即先得到的消息先处理。队列中的消息以链表的结构进行保存,Message中包含一个next变量,该变量指向下一个消息。

MQ主要函数是“取出消息”和“添加消息”,分别是next()和enquenceMessage().

取出消息和拿出消息涉及到JNI函数,就没往下看。

3.Handler

刚刚说了,在Looper.loop()函数中,当取出消息后,会回调msg.target对象的handleMessage()函数,而msg.target的类型就是Handler

我们一般用Handler向消息队列中发送消息,并重载Handler类的handlerMessage()函数添加消息处理代码。

我们一般在Activity对象的初始化代码中添加Handler对象,但我们并没用用Looper,这是因为在Activity对象被构造前,Activity所在的线程已经执行了Looper.prepare()函数。

一个线程可以包含多个Handler对象,在Looper.loop()函数中,不同的Message对应不用的Handler对象,从而回调不同的handleMessage()函数。类似多态。

以上参考《android内核剖析》,加之本人拙见,请大神拍砖。

1 0