Handler机制算是我入门源码的第一节。看得比较仔细。体会较多。mark一下。
顺序:先科普一下Handler基本功,然后再细讲下源码
一、Handler目的:
目的:Handler机制来处理了子线程去更新UI线程控件问题。
二、handler,messagequeue,looper,message关系图:
其实各种书籍上都有这么一张图。但是主要是学习源码,所以还是自己手画一张“流程图”。
三、handler知识点总结:
(若以下总结都能理解,那么可以不再看本文后续源码分析;)
1)handler、Looper、Messagequeue初始化总结:在主UI实例化Looper或者子线程手工实例化looper。在Looper中实例化Messagequeue。在handler初始化在主线程或者子线程中,且handler初始化只获取looper对象,获取Messagequeue对象,因此必须先有Looper实例再有handler实例,否则handler无法获取looper、Messagequeue。
2)hanlder中写了操作主UI线程的handlemessage空方法、使用handler实例在子线程中发送消息Message
3)Looper初始化:一个线程只有一个Looper,Looper管理Messagequeue
4)主UI线程(ActivityThread)创建Looper对象,而Looper创建了Messagequeue对象(可通过其他方式创建looper)
5)在handler里使用queue(Messagequeue对象),equeueMessage插入消息到Messagequeue,在Looper的loop()方法里调用handler对象的dispatchMessage()分发消息。并通过handler的handlerMessage()方法使主UI改变。
6)Messagequeue对象和Message对象
四、逐步分析handler源码
1)handler、Looper、Messagequeue初始化:
由于初始化顺序必然是Looper ==> Messagequeue ==> handler。所以我也按照此顺序分析源码。
四、1)Looper获取:
当我启动一个程序。按照如下顺序:
ActivityManager的startActivity()==>ActivityThread的main()==》Looper.prepareMainLooper()实例化主UI线程Looper
以上实例源码,部分如下:
ActivityManager的startActivity()
/**
* Start an activity in this task. Brings the task to the foreground. If this task
* is not currently active (that is, its id < 0), then a new activity for the given
* Intent will be launched as the root of the task and the task brought to the
* foreground. Otherwise, if this task is currently active and the Intent does not specify
* an activity to launch in a new task, then a new activity for the given Intent will
* be launched on top of the task and the task brought to the foreground. If this
* task is currently active and the Intent specifies {@link Intent#FLAG_ACTIVITY_NEW_TASK}
* or would otherwise be launched in to a new task, then the activity not launched but
* this task be brought to the foreground and a new intent delivered to the top
* activity if appropriate.
*
* <p>In other words, you generally want to use an Intent here that does not specify
* {@link Intent#FLAG_ACTIVITY_NEW_TASK} or {@link Intent#FLAG_ACTIVITY_NEW_DOCUMENT},
* and let the system do the right thing.</p>
*
* @param intent The Intent describing the new activity to be launched on the task.
* @param options Optional launch options.
*
* @see Activity#startActivity(android.content.Intent, android.os.Bundle)
*/
public void startActivity(Context context, Intent intent, Bundle options) {
ActivityThread thread = ActivityThread.currentActivityThread();
thread.getInstrumentation().execStartActivityFromAppTask(context,
thread.getApplicationThread(), mAppTaskImpl, intent, options);
}
此处ActivityThread.currentActivityThread();
public static ActivityThread currentActivityThread() {
return sCurrentActivityThread;
}
一个单例模式的ActivityThread,简单看下定义。
/** Reference to singleton {@link ActivityThread} */
private static ActivityThread sCurrentActivityThread;
ActivityThread的main()
public static void main(String[] args) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
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);
Environment.initForCurrentUser();
// Set the reporter for event logging in libcore
EventLogger.setReporter(new EventLoggingReporter());
AndroidKeyStoreProvider.install();
// Make sure TrustedCertificateStore looks in the right place for CA certificates
final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
TrustedCertificateStore.