Android程序启动 -> Activity加载并调用生命周期onCreate -> Activity调用setContentView -> UI绘制
我们都知道Android程序的启动入口是ActivityThread.main函数,那么看一看main函数是如何进行启动的。
ActivityThread.class
public static void main(String[] args) {
…
ActivityThread thread = new ActivityThread();
thread.attach(false);
…
}
private void attach(boolean system) {
…
final IActivityManager mgr = ActivityManager.getService();
try {
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
…
}
由上面的源码可知,我们在main函数中做了两件事情:
在attach方法中,也做了两件事情:
通过ActivityManager.getService()获取到Activity管理器接口对象,那么如何拿到的呢?我们来看下源码实现:
ActivityManager.class
/**
* @hide
*/
public static IActivityManager getService() {
return IActivityManagerSingleton.get();
}
private static final Singleton IActivityManagerSingleton =
new Singleton() {
@Override
protected IActivityManager create() {
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
final IActivityManager am = IActivityManager.Stub.asInterface(b);
return am;
}
};
在APP进程启动之后,AMS便会跨binder调用到ApplicationThread的scheduleLaunchActivity,启动Activity。
详细的介绍请参照深入理解Activity——Token之旅
通过上面的分析,我们知道ApplicationThread这个对象在启动过程中起着至关重要的作用,来看下它的源码:
ApplicationThread类里面都干了什么事情?
ApplicationThread.class
private class ApplicationThread extends IApplicationThread.Stub {
public final void schedulePauseActivity(IBinder token, boolean finished, ...
public final void scheduleStopActivity(IBinder token, boolean showWindow, ...
@Override public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident, ...
...
如上图所示,一堆的schedule方法,按照字面翻译,我们可以猜测出,这个是在Activity状态变化时去调用的方法。
在诸多的schedule方法里面,根据注释得知,scheduleLaunchActivity是在Activity加载的时候调用,我们来看一下:
ApplicationThread.class
// we use token to identify this activity without having to send the
// activity itself back to the activity manager. (matters more with ipc)
@Override
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
int procState, Bundle state, PersistableBundle persistentState,
List pendingResults, List pendingNewIntents,
boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {
updateProcessState(procState, false);
ActivityClientRecord r = new ActivityClientRecord();
...
updatePendingConfiguration(curConfig);
sendMessage(H.LAUNCH_ACTIVITY, r);
}
根据代码我们可以分析
ApplicationThread.class
private void sendMessage(int what, Object obj) {
sendMessage(what, obj, 0, 0, false);
}
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);
}
final H mH = new H();
private class H extends Handler {
...
}
通过以上代码可以知道,将创建的ActivityClientRecord对象以及标志位通过handler发送出去,那我们顺着找到mH的handleMessage方法
private class H extends Handler {
...
public void handleMessage(Message msg) {
if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
switch (msg.what) {
case LAUNCH_ACTIVITY: {
...
final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
...
handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
...
} break;
...
}
...
}
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
...
Activity a = performLaunchActivity(r, customIntent);
...
}
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
...
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
...
}
对应着LAUNCH_ACTIVITY,调用到了handleLaunchActivity函数-> performLaunchActivity函数,在performLaunchActivity函数中,我们可以看到 mInstrumentation.callActivityOnCreate的字样,猜的没错的话,这就是调用Activity的onCreate函数的入口了,我们看下源码:
Instrumentation.class
/**
* Perform calling of an activity's {@link Activity#onCreate}
* method. The default implementation simply calls through to that method.
* @param activity The activity being created.
* @param icicle The previously frozen state (or null) to pass through to
* @param persistentState The previously persisted state (or null)
*/
public void callActivityOnCreate(Activity activity, Bundle icicle,
PersistableBundle persistentState) {
prePerformCreate(activity);
activity.performCreate(icicle, persistentState);
postPerformCreate(activity);
}
Activity.class
final void performCreate(Bundle icicle) {
performCreate(icicle, null);
}
final void performCreate(Bundle icicle, PersistableBundle persistentState) {
...
if (persistentState != null) {
onCreate(icicle, persistentState);
} else {
onCreate(icicle);
}
...
}
public void onCreate(@Nullable Bundle savedInstanceState,
@Nullable PersistableBundle persistentState) {
onCreate(savedInstanceState);
}
总结一下调用关系,Instrumentation. callActivityOnCreate-> Activity. performCreate->Activity.onCreate。
到此为止,我们的整个APP已经成功启动啦~
总结一下:
2.Activity调用setContentView做了什么?
敬请期待