Handler,Looper,MessageQueue的实现

所要用到的android源码路径:

ActivityThread源码路径:android-4.0.3_r1\frameworks\base\core\java\android\app\ActivityThread

Activity源码路径:android-4.0.3_r1\frameworks\base\core\java\android\app\Activity

Handler源码路径:android-4.0.3_r1\frameworks\base\core\java\android\os\Handler

Looper源码路径:android-4.0.3_r1\frameworks\base\core\java\android\os\Looper

Message源码路径:android-4.0.3_r1\frameworks\base\core\java\android\os\Message

MessageQueue源码路径:android-4.0.3_r1\frameworks\base\core\java\android\os\MessageQueue

我们从使用handler发送一条message到接收进行处理的这个过程来理解Handler,Looper,MessageQueue的实现,在Activity主线程中,会默认

创建一个Looper对象,在这个Looper类中会创建一个MessageQueue的消息队列,然后主线程会调用Looper的的loop()方法循环遍历这个消息队

列,如果有消息则会通过Handler对象将消息传递到handlerMessage方法中进行处理,如果Hanlder对象为空也就是没有创建Hanlder对象则会将

这条消息丢掉。那么消息的发送是怎样的呢?我们创建一个Handler对象,使用这个对象发送Message,其实是使用Looper对象传递进来的

MessageQueue,通过这个消息队列的引用将Message放进消息队列中,由于Looper会遍历这个队列,所以Handler对象发送msg,将其放进消

息队列,Looper遍历消息队列将消息取出,然后传递给Hanlder进行处理,这样一个消息的发送与接收就完成了。

首先我们根据Handler的构造函数来了解Handler的几种使用方法,从API中我们知道Handler有四个构造函数,分别是:

Handler()Handler(callback)Handler(looper)Handler(looper, callback)一、不带参数的Handler()构造函数,其使用的是主线程默认的Looper对象以及MessageQueueHandler handler2 = new Handler(){public void handleMessage(Message msg) {};};handler2.sendEmptyMessage(30);直接在Activity中new一个Handler对象,并且重载handlerMessage方法就能够实现Message的发送与接收。

二、Handler(callback)构造函数,带了一个Hanlder类中的一个Callable接口对象作为参数,看源码就能够很清楚知道,他的作用其实是将handlerMessage

方法给独立出去,也就是在Activity中如果handlerMessage中的代码量太多,使用这个构造函数去创建对象,就能够将handlerMessage方法不放在

Activity中。

public class MyHandler implements Handler.Callback{@Overridepublic boolean handleMessage(Message arg0) {return false;}}先实现Hanlder.Callback接口,丛杂handlerMessage方法,在这里进行消息的处理MyHandler callback = new MyHandler();Handler handler3 = new Handler(callback);handler3.sendEmptyMessage(20);在Activity中创建Handler对象,将Callback对象作为参数传递进去,然后使用handler发送Message,就能够在MyHandler中接收消息进行处理。

三、Handler(looper)构造函数,带了一个自定义的Looper对象作为参数,所以我们只要自定义一个Looper,然后将该Looper对象传递进去就能够正常

的进行消息发送与接收。但是我们不必要真的去自定义一个Looper类,我们只需要继承android已经实现好的HandlerThread线程,就能够自定义一个

Looper类

public class MyThread extends HandlerThread{//HandlerThread类是android中已经继承Thread的类,他已经帮你实现了Looper对象的创建//所以如果我们在实现Handler时,需要自定义Looper对象,则直接继承此类就行。public MyThread(String name) {super(name);}@Overrideprotected void onLooperPrepared() {//这个方法是在Looper.loop()被调用前在线程HandlerThread的run方法中被调用//所以如果要在这之前做什么操作,就需要重载这个方法Log.i("MyThread", "onLooperPrepared");super.onLooperPrepared();}}MyThread thread = new MyThread("thread");thread.start();Looper looper = thread.getLooper();Handler handler1 = new Handler(looper){public void handleMessage(Message msg) {}};handler1.sendEmptyMessage(10);这样我们就能够使用自定义的Looper进行消息的发送与接收,而不必使用Activity帮我们已经创建好的默认的Looper对象。

四、Handler(looper, callback)构造函数,知道了前面三种构造函数之后,这种就能够很容易理解了:使用自定义Looper,将handlerMessage方法

从创建Handler对象的类中独立出去。

Handler的详细使用方法就介绍完了,接下来我们就来分析相关类的源码,来彻底了解其运作过程。

首先我们来看看Looper的实现过程,我们知道在创建一个Activity时,其主UI主线程ActivityThread中会默认创建一个Looper对象,那么这个对象是在

什么地方创建的呢?

public static void main(String[] args) {SamplingProfilerIntegration.start();// CloseGuard defaults to true and can be quite spammy. We// disable it here, but selectively enable it later (via// StrictMode) on debug builds, but using DropBox, not logs.CloseGuard.setEnabled(false);Process.setArgV0("<pre-initialized>");Looper.prepareMainLooper();if (sMainThreadHandler == null) {sMainThreadHandler = new Handler();}ActivityThread thread = new ActivityThread();thread.attach(false);if (false) {Looper.myLooper().setMessageLogging(newLogPrinter(Log.DEBUG, "ActivityThread"));}Looper.loop();throw new RuntimeException("Main thread loop unexpectedly exited");}step1:从上面ActivityThread源码中我们可以看见,这个main方法是主线程的启动的地方,首先他调用了Looper的静态prepareMainLooper()方法: public static void prepareMainLooper() {prepare();setMainLooper(myLooper());myLooper().mQueue.mQuitAllowed = false;} public static void prepare() {if (sThreadLocal.get() != null) {throw new RuntimeException("Only one Looper may be created per thread");}sThreadLocal.set(new Looper());} private synchronized static void setMainLooper(Looper looper) {mMainLooper = looper;} public static Looper myLooper() {return sThreadLocal.get();} private Looper() {mQueue = new MessageQueue();mRun = true;mThread = Thread.currentThread();}在上面源码中我们可以看出,prepareMainLooper方法中调用prepare()方法创建了一个Looper对象,并将这个Looper对象放进了ThreadLocal中,将

Looper对象放进ThreadLocal中的作用是,ThreadLocal会维护Looper对象中变量的副本。具体可以参考ThreadLocal的使用方法。然后调用myLooper

方法从ThreadLocal中获取Looper对象,并将其赋值给主线程Looper对象的引用。在Looper构造函数中我们可以看见,他创建了一个MessageQueue

如果你曾歌颂黎明,那么也请你拥抱黑夜

Handler,Looper,MessageQueue的实现

相关文章:

你感兴趣的文章:

标签云: