最近会将以前阅读过的一些源码做些沉淀与总结
我们知道现在大多数的GUI框架都是采用单线程模型来处理消息队列和UI更新的,Android自然也是如此。
启动
在APK首次启动的时候,Zygote进程会fork个子进程,并在子进程中调用ActivityThread的main函数,主线程的消息队列和ActivityThread实例的初始化都是在此完成的。
与AMS的通信
ActivtyManagerService控制着Activity的启动与生命周期,并通过ApplicationThread与ActivityThread进行IPC通信。
onCreate
AMS通过ApplicationThread的scheduleLaunchActivity启动一个新的Activity,并通过Handler调用ActivityThread的handleLaunchActivity方法。
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
......
Activity a = performLaunchActivity(r, customIntent);
if (a != null) {
r.createdConfig = new Configuration(mConfiguration);
Bundle oldState = r.state;
handleResumeActivity(r.token, false, r.isForward,
!r.activity.mFinished && !r.startsNotResumed);
......
}
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
......
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
}
else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
......
}
Instrumentation.java
public void callActivityOnCreate(Activity activity, Bundle icicle, PersistableBundle persistentState) {
prePerformCreate(activity);
activity.performCreate(icicle, persistentState);
postPerformCreate(activity);
}
Activity.java
final void performCreate(Bundle icicle, PersistableBundle persistentState) {
onCreate(icicle, persistentState);
mActivityTransitionState.readState(icicle);
performCreateCommon();
}
onResume
ActivtyThread通过performLaunchActivity的调用做些Activity的初始化,包括创建实例和最终调用Activity的onCreate方法。之后通过调用handleResumeActivity方法
final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward, boolean reallyResume) {
......
// TODO Push resumeArgs into the activity for consideration
ActivityClientRecord r = performResumeActivity(token, clearHide);
......
if (r.window == null && !a.mFinished && willBeVisible) {
if (a.mVisibleFromClient) {
a.mWindowAdded = true;
wm.addView(decor, l);
}
}
.....
public final ActivityClientRecord performResumeActivity(IBinder token, boolean clearHide) {
......
r.activity.performResume();
......
}
ActivtyThread通过handleResumeActivity调用Activity的onResume方法之后,并在当前Activity的Window为null等情况下,调用WindowMangerGlobal的addView方法将Activity的decorView添加在Window中。
WindowMangerGlobal.java
public void addView(View view, ViewGroup.LayoutParams params,Display display, Window parentWindow) {
......
root = new ViewRootImpl(view.getContext(), display);
view.setLayoutParams(wparams);
try {
root.setView(view, wparams, panelParentView);
} catch (RuntimeException e) {
......
}
重点来了,在Activity的onCreate和onResume调用之后,ActivityThread才创建了ViewRootImpl,并调用setView方法
ViewRootImpl.java
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
......
requestLayout();
......
view.assignParent(this);
......
}
@Override
public void requestLayout() {
if (!mHandlingLayoutInLayoutRequest) {
checkThread();
mLayoutRequested = true;
scheduleTraversals();
}
}
void invalidate() {
mDirty.set(0, 0, mWidth, mHeight);
if (!mWillDrawSoon) {
scheduleTraversals();
}
}
在此才会检查当前线程是否为主线程,并设置了view的parent,之后一些系统view组件或自定义view会通过调用requestlayout或者invalidate实现view的重新渲染(scheduleTraversals通过Handelr实现)。
结论
通过上诉Activity的启动过程可知,我们在Activity的onCreate和onResume中,通过子线程的确可以实现更新某些系统view组件。
@Override
protected void onResume() {
super.onResume();
new NoUIThread().start();
}
class NoUIThread extends Thread {
@Override
public void run() {
mNoUITextView.setText("Penner");
}
}
网友评论