版权声明
版权声明:本文为博主原创文章,转载请注明出处+地址
绘制流程概览
Android程序启动 -> Activity加载并调用生命周期onCreate -> Activity调用setContentView -> UI绘制
Android启动流程分析
我们都知道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函数中做了两件事情:
- 生成一个ActivityThread对象
- 调用该对象的attach方法
在attach方法中,也做了两件事情:
- 获取了IActivityManager的对象实例
- 执行该对象的attachApplication方法
通过ActivityManager.getService()获取到Activity管理器接口对象,那么如何拿到的呢?我们来看下源码实现:
ActivityManager.class
/**
* @hide
*/
public static IActivityManager getService() {
return IActivityManagerSingleton.get();
}
private static final Singleton<IActivityManager> IActivityManagerSingleton =
new Singleton<IActivityManager>() {
@Override
protected IActivityManager create() {
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
final IActivityManager am = IActivityManager.Stub.asInterface(b);
return am;
}
};
- 服务管理器通过getService拿到了ActivityService 的IBinder对象,通过跨进程获取到am对象。
- mgr.attachApplication(mAppThread)是将ApplicationThread和ActivityManagertService相关联。
在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<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {
updateProcessState(procState, false);
ActivityClientRecord r = new ActivityClientRecord();
...
updatePendingConfiguration(curConfig);
sendMessage(H.LAUNCH_ACTIVITY, r);
}
根据代码我们可以分析
- 创建了ActivityClientRecord对象
- 将ActivityClientRecord对象以及标志位LAUNCH_ACTIVITY发送出去
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做了什么?
敬请期待
网友评论