理解android UI Thread
什么叫做UI Thread
我通常的理解是
1. 执行ui绘制的地方,measure layout draw,
2. android组件activity,service,broadcastreceiver的生命周期都是在ui thread中执行的。如果在ui thread中执行耗时过长的任务,会导致anr
但是为什么会这样,并没有深入理解
UI Thread初始化
我们知道android 进程的初始化后会执行ActivityThread.main(String[] args)方法,不了解的可以看下这里android应用程序初始化流程
看下代码:
public static void main(String[] args) {
.
.
.
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
}
.
.
.
}
最关键的代码部分Looper.prepareMainLooper()
这里是初始化主线程的Looper。
看到这可以想到,其实UI Thread其实和HanderThread没什么区别。都是在线程中不断Looper.loop(),然后执行handler.handleMessage(Message)
view的绘制是怎么抛到UI Thread中执行的
我们知道view的绘制会从ViewRootImpl.performTraversals()开始,而这个方法是怎么执行起来的呢?
简单解释下:
1. performTraversal()是在mTraversalRunnable中执行的
2. mTraversalRunnable是通过mChoreographer.postCallback调用
3. Choreographer是一个ui绘制的管理类,通过其类成员mFrameHandler来执行的
4. mFrameHandler的初始化参数是Looper.myLooper(), 当这行代码在uiThread中执行的时候looper.myLooper==looper.mainLooper,而实际上这行代码就是在uiThread中执行的
Activity的生命周期是怎么在UI Thread中执行的
源码的角度
csdn做的图也是醉了,还是我不会用?(编辑模式下完全是正常的)
看下ApplictionThread.scheduleLaunchActivity()代码
@Override
public final void scheduleLaunchActivity(Intent intent, ...) {
updateProcessState(procState, false);
ActivityClientRecord r = new ActivityClientRecord();
.
.
.
sendMessage(H.LAUNCH_ACTIVITY, r);
}
调用到ActivityThread.sendMessage() 看代码:
private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
if (DEBUG_MESSAGES) Slog.v(
TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
+ ": " + arg1 + " / " + obj);
Message msg = Message.obtain();
msg.what = what;
msg.obj = obj;
msg.arg1 = arg1;
msg.arg2 = arg2;
if (async) {
msg.setAsynchronous(true);
}
mH.sendMessage(msg);
}
会用到mH,mH是在Activity.main()中初始化的。也就是说handler是主线程的handler。
侧面验证
activity.runOnUiThread()
public final void runOnUiThread(Runnable action) {
if (Thread.currentThread() != mUiThread) {
mHandler.post(action);
} else {
action.run();
}
}
可以看到判断是不是ui thread的关键代码
Thread.currentThread() != mUiThread
而 mUiThread thread的赋值是在Activity.onAttach()方法里
final void attach(Context context, ActivityThread aThread, ...) {
.
.
.
mUiThread = Thread.currentThread();
}
(attach的执行时机是在ActivityThread.performLaunchActivity里在activity类初始化之后,activity生命周期onCreate之前执行)
总结:
1.activity的生命周期是在主线程的任务队列(messageQueue)中等待执行的
2.activity中的mUiThread是ui线程的引用