2015年1月30日 13:51:32 晴
handler机制详解
- handler机制
- 一个Activity启动的时候,先是ActivityManager先为每一个application创建一个ActivityThread,然后调用ActivityThread里面的main方法,其中有一个 代码
Looper.prepareMainLooper();
而Looper类中 Looper.prepareMainLooper();方法调用的是public static final void prepare() { if (sThreadLocal.get() != null) { throw new RuntimeException("Only one Looper may be created per thread"); } sThreadLocal.set(new Looper()); }
从线程级共享对象中设置一个looper对象,如果这个对象已经被创建过,则抛出异常接下来回到ActivityThread接着看它的main方法接下来有一行代码Looper.loop();
Looper类中
public static final void loop() { Looper me = myLooper(); MessageQueue queue = me.mQueue; while (true) { Message msg = queue.next(); // might block //if (!me.mRun) { // break; //} if (msg != null) { if (msg.target == null) { // No target is a magic identifier for the quit message. return; } if (me.mLogging!= null) me.mLogging.println( ">>>>> Dispatching to " + msg.target + " " + msg.callback + ": " + msg.what ); msg.target.dispatchMessage(msg); if (me.mLogging!= null) me.mLogging.println( "<<<<< Finished to " + msg.target + " " + msg.callback); msg.recycle(); } } }
说明一个Application应用中,主线程ActivityThread一直存在一个looper死循环,
处理界面更新和activity生命周期及service等操作还是看它的第一行
Looper me = myLooper();
接着往下看 myLooper()代码;public static final Looper myLooper() { return (Looper)sThreadLocal.get(); }
从线程级共享对象中获取Looper.prepareMainLooper()存入的looper对象,而且因为上面的一个判断,所以每个界面取出来的looper都是相同的;这里实现了多个Activity取得都是同一个Looper - 主线程ActivityThread中还有一个点 就是它的handler是它自己自定义的
private final class H extends Handler { public static final int LAUNCH_ACTIVITY = 100; public static final int PAUSE_ACTIVITY = 101; public static final int PAUSE_ACTIVITY_FINISHING= 102; public static final int STOP_ACTIVITY_SHOW = 103; public static final int STOP_ACTIVITY_HIDE = 104; public static final int SHOW_WINDOW = 105; public static final int HIDE_WINDOW = 106; public static final int RESUME_ACTIVITY = 107; public static final int SEND_RESULT = 108; public static final int DESTROY_ACTIVITY = 109; public static final int BIND_APPLICATION = 110; public static final int EXIT_APPLICATION = 111; public static final int NEW_INTENT = 112; public static final int RECEIVER = 113; public static final int CREATE_SERVICE = 114; public static final int SERVICE_ARGS = 115; public static final int STOP_SERVICE = 116; public static final int REQUEST_THUMBNAIL = 117; public static final int CONFIGURATION_CHANGED = 118; public static final int CLEAN_UP_CONTEXT = 119; public static final int GC_WHEN_IDLE = 120; public static final int BIND_SERVICE = 121; public static final int UNBIND_SERVICE = 122; public static final int DUMP_SERVICE = 123; public static final int LOW_MEMORY = 124; public static final int ACTIVITY_CONFIGURATION_CHANGED = 125; public static final int RELAUNCH_ACTIVITY = 126; public static final int PROFILER_CONTROL = 127; public static final int CREATE_BACKUP_AGENT = 128; public static final int DESTROY_BACKUP_AGENT = 129; public static final int SUICIDE = 130; public static final int REMOVE_PROVIDER = 131; public static final int ENABLE_JIT = 132; public static final int DISPATCH_PACKAGE_BROADCAST = 133; public static final int SCHEDULE_CRASH = 134;
我们可以看懂很多的状态,当状态改变时发送不同Message的H消息,从而进行相应的处理 -
最终总结
-
先ActivityThread被ActivityManager创建,然往ThreadLocal里面存一个创建的Looper,接下来执行Loop 一直阻塞操作更新UI和生命周期,用户点击后发消息时,调用的是sendMessageAtTime()方法,然后被放入到消息队列MessageQueue中,等待Looper去next获取,当获取到了时候,looper调用的msg.target的dispatchMessage方法,这个target指的就是与之对应的handler,最后调用的handler的handeMessage方法,实现多线程之间的通讯
- 子线程中可以有handler,但是必须有一个与之对应的looper,调用looper.prepare来初始化一个looper,其中在它的构造函数中已经创建了一个与之对应的消息队列MessageQueue,然后调用looper.loop在子线程中开启轮询,即可实现子线程自己的消息队列,这点有些类似于线程池
-