1.前言
在Activity启动流程(上)这篇文章的结尾说到activity启动的流程进入到ActivityManagerService以socket方式通过Zygote进程孵化一个应用进程并执行应用进程的main方法,而这个应用进程的入口函数main方法在ActivityThread类中,因此ActivityThread类就顺理成章的成为了应用程序的主线程。下面我们结合ActivityThread来继续分析activity启动流程。
2.activity启动流程(下)
关于ActivityThread的main方法,在Android 异步消息处理机制曾经提到过,当时主要是分析了异步消息机制,现在我们再来看看main方法里面还有什么值得注意的:
public static void main(String[] args) {
......
//1.创建消息机制的Loop,同时也会创建消息队列
Looper.prepareMainLooper();
//4.创建ActivityThread实例,并初始化thread
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (sMainThreadHandler == null) {//2.获得handler对象
sMainThreadHandler = thread.getHandler();
}
......
//3.进入消息循环
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
注释1.2.3,曾经详细提到过,主要是构建了一个异步消息机制,当其他线程需要和主线程交互的时候,可以通过主线程的handler往messageQueue中发送消息,通过handler来处理,这里不再过多说明了。下面重点看下注释4:说到这里,记得第一次看ActivityThread的main方法时,觉得很困惑,main方法为什么这么简单,感觉什么都没有。“应用程序不是在这里启动的吗?为什么找不到activity启动的代码呢?”在分析了Android异步消息机制机制之后,这个困扰已久的问题终于解开了,答案就在注释4的地方。我们可以大胆推测,在thread.attach(false)肯定执行了一系列的逻辑,然后向主线程的messageQueue中发送消息,通过主线程的handler处理问题,其中包括activity的启动。那下面就来具体瞧一瞧,我们的推测是否正确。
接下来我们看下ActivityThread 的attach方法,分析ActivityThread 是如何初始化的:
private void attach(boolean system) {
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) {
......
//1.得到ActivityManagerService在应用进程的代理对象
final IActivityManager mgr = ActivityManagerNative.getDefault();
try {
//2.通过binder跨进程调用ActivityManagerService的attachApplication方法
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
// Ignore
}
......
} else {
......
}
这段代码有两段注释,先看注释1,同Activity启动流程(上)分析的一样,注释1处会得到一个ActivityManagerService在应用进程的代理对象mgr,然后再注释2处,通过binder进程间调用到ActivityManagerService的attachApplication方法中:
@Override
public final void attachApplication(IApplicationThread thread) {
synchronized (this) {
......
attachApplicationLocked(thread, callingPid);
......
}
}
接着调用ActivityManagerService的attachApplication方法:
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid) {
......
try {
......
//1.启动Application
thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
enableTrackAllocation, isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(mConfiguration), app.compat,
getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked());
......
} catch (Exception e) {
......
return false;
}
......
if (normalMode) {
try {
//2.启动activity
if (mStackSupervisor.attachApplicationLocked(app)) {
didSomething = true;
}
} catch (Exception e) {
Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
badApp = true;
}
}
......
return true;
}
这段代码我们还是看两个注释的地方:注释1处会启动Application(调用Application的oncreat方法),2处会启动一个activity(执行activity的启动过程的生命周期方法)。下面我们详细分析这两个过程。
Application启动的流程
先看注释1处thread的bindApplication方法,在这之前我们先要弄清楚thread是个啥?回到attachApplicationLocked的参数列表中,thread是一个IApplicationThread 类型的一个变量,实质上是ApplicationThread这个binder对象在ActivityManagerService的代理。因此thread的bindApplication方法最终会进入ApplicationThread的bindApplication方法:
public final void bindApplication(String processName, ApplicationInfo appInfo,
List<ProviderInfo> providers, ComponentName instrumentationName,
ProfilerInfo profilerInfo, Bundle instrumentationArgs,
IInstrumentationWatcher instrumentationWatcher,
IUiAutomationConnection instrumentationUiConnection, int debugMode,
boolean enableOpenGlTrace, boolean isRestrictedBackupMode, boolean persistent,
Configuration config, CompatibilityInfo compatInfo, Map<String, IBinder> services,
Bundle coreSettings) {
......
AppBindData data = new AppBindData();
data.processName = processName;
data.appInfo = appInfo;
data.providers = providers;
data.instrumentationName = instrumentationName;
data.instrumentationArgs = instrumentationArgs;
data.instrumentationWatcher = instrumentationWatcher;
data.instrumentationUiAutomationConnection = instrumentationUiConnection;
data.debugMode = debugMode;
data.enableOpenGlTrace = enableOpenGlTrace;
data.restrictedBackupMode = isRestrictedBackupMode;
data.persistent = persistent;
data.config = config;
data.compatInfo = compatInfo;
data.initProfilerInfo = profilerInfo;
//通过handler类型的变量mH发送消息到主线程
sendMessage(H.BIND_APPLICATION, data);
}
这里有一点需要注意,在Activity启动过程及界面绘制流程解析开篇这篇文章中说过,binder service会单独运行在一个线程,所以在我们这里,ApplicationThread当做binder service,它的方法都是运行在非主线程,从而与主线程(一个异步线程)之间的通信需要通过handler来处理。我们来看下ApplicationThread的sendMessage方法分析是否通过主线程的handler来发送与处理消息,最终调用到ApplicationThread4个参数的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是一个Handler类型的变量,且是ActivityThread的一个成员变量,因此可以向主线程的messageQueue中发送消息。然后会通过mH来处理这个消息:
public void handleMessage(Message msg) {
......
switch (msg.what) {
case LAUNCH_ACTIVITY: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
r.packageInfo = getPackageInfoNoCheck(
r.activityInfo.applicationInfo, r.compatInfo);
handleLaunchActivity(r, null);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
} break;
......
case BIND_APPLICATION:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
AppBindData data = (AppBindData)msg.obj;
handleBindApplication(data);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
......
}
......
}
mH的handleMessage方法根据不同的消息标示,处理不同的消息。这里的标示是BIND_APPLICATION,因此会进入ActivityThread的handleBindApplication方法:
private void handleBindApplication(AppBindData data) {
......
//1.保证了一个应用程序只有一个Instrumentation实例
if (data.instrumentationName != null) {
......
} else {
//2.创建一个Instrumentation管理activity的生命周期
mInstrumentation = new Instrumentation();
}
......
try {
// If the app is being launched for full backup or restore, bring it up in
// a restricted environment with the base application class.
//3.创建一个Application实例,一个应用程序只有一个Application实例
Application app = data.info.makeApplication(data.restrictedBackupMode, null);
mInitialApplication = app;
......
try {
//4.调用Application的oncreate方法
mInstrumentation.callApplicationOnCreate(app);
} catch (Exception e) {
if (!mInstrumentation.onException(app, e)) {
throw new RuntimeException(
"Unable to create application " + app.getClass().getName()
+ ": " + e.toString(), e);
}
}
} finally {
StrictMode.setThreadPolicy(savedPolicy);
}
}
这段代码有4个注释的地方需要看一下,首先注释1.2处,会创建一个Instrumentation对象的实例。还记得在Activity的启动流程(上)曾经说过,Instrumentation对象会管理Activity的生命周期方法,所以在执行Activity的生命周期方法时会先创建一个Instrumentation实例用来管理Activity的周期方法,且Instrumentation在应用程序中只持有一个实例。注释3处,创建了一个Application实例,这也很好理解,在开发中我们都知道一个应用Application代表一个应用程序,且Application先于Activity加载到内存中。稍后会分析Application实例是如何创建的,为什么一个应用程序只有一个Application实例。注释4处会调用Application的oncreate方法,这也是我们平时开发中一个应用最先执行的方法,通常我们会在这个方法中完成一些初始化的操作。
public void callApplicationOnCreate(Application app) {
//直接执行了Application的onCreate方法
app.onCreate();
}
下面我们再来详细的分析,application是如何创建的,为什么一个应用只有一个application实例。
注释3处的data.info实际上是一个LoadedApk,然后调用LoadedApk的makeApplication方法创建一个application实例:
public Application makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation) {
//如果mApplication不为空,直接返回mApplication,这也就解释了为什么一个应用程序只有一个Application实例
if (mApplication != null) {
return mApplication;
}
Application app = null;
......
try {
java.lang.ClassLoader cl = getClassLoader();
if (!mPackageName.equals("android")) {
initializeJavaContextClassLoader();
}
//1.创建一个ContextImpl 对象
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
//2.通过Instrumentation的newApplication方法创建一个application实例
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
//3.将application注入appContext
appContext.setOuterContext(app);
} catch (Exception e) {
......
}
......
return app;
}
这段代码的注释1处,通过ContextImpl的createAppContext方法实例化一个创建Application所需要的ContextImpl,然后在注释2处调用Instrumentation的newApplication创建一个Application实例:
public Application newApplication(ClassLoader cl, String className, Context context)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
return newApplication(cl.loadClass(className), context);
}
接着调用Instrumentation两个参数的newApplication方法:
static public Application newApplication(Class<?> clazz, Context context)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
Application app = (Application)clazz.newInstance();
//将context注入application,从而Application持有context的引用
//这里context是一个抽象类,具体的实现类是ContextImpl
app.attach(context);
return app;
}
这段代码可以看到Application是通过反射创建的实例,即最终的应用程序的Application是通过反射创建的,然后将LoadedApk的makeApplication方法中创建的ContextImpl实例注入到application中,从而application可以调用ContextImpl的方法,而在是个上段代码注释3处,可以看到appContext.setOuterContext(app),这句代码意味着新建的application被注入到了ContextImpl中,从而ContextImpl持有application的引用,可以调用application的一些方法。
至此我们可以看到Application实例的创建和oncreate方法何时被调用的,所以Application的启动我们就分析完了。这时回到我们文初的一个问题:ActivityThread的main方法为什么比较简短,应用程序到底是如何启动的?现在我们应该清楚了,android主线程是基于消息驱动的,main方法在进入消息循环之前,通过thread.attach(false)打开了一个分支,然后这个分支将问题发送到主线程的messagequeue中处理,因此虽然main方法看似没参与应用程序的启动过程,实质上还是参与了整个启动过程,依然是android程序的主入口。下面再次贴出main方法的代码,以便加深映像:
public static void main(String[] args) {
......
//1.创建消息机制的Loop,同时也会创建消息队列
Looper.prepareMainLooper();
//4.创建ActivityThread实例,并初始化thread
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (sMainThreadHandler == null) {//2.获得handler对象
sMainThreadHandler = thread.getHandler();
}
......
//3.进入消息循环
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
activity的启动过程
在分析了application的启动之后,我们接着分析activity的启动过程。上文已经说到过ActivityManagerService的attachApplication方法中有两段比较重要的代码。一段是Application的启动,我们已经分析过了,下面我们来看第二段activity的启动,再次贴出ActivityManagerService的attachApplication方法的代码熟悉一下:
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid) {
......
try {
......
//1.启动Application
thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
enableTrackAllocation, isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(mConfiguration), app.compat,
getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked());
......
} catch (Exception e) {
......
return false;
}
......
if (normalMode) {
try {
//2.启动activity
if (mStackSupervisor.attachApplicationLocked(app)) {
didSomething = true;
}
} catch (Exception e) {
Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
badApp = true;
}
}
......
return true;
}
接着会调用ActivityStackSupervisor的attachApplicationLocked方法启动activity:
boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
final String processName = app.processName;
boolean didSomething = false;
for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
final ActivityStack stack = stacks.get(stackNdx);
if (!isFrontStack(stack)) {
continue;
}
ActivityRecord hr = stack.topRunningActivityLocked(null);
if (hr != null) {
if (hr.app == null && app.uid == hr.info.applicationInfo.uid
&& processName.equals(hr.processName)) {
try {
//调用realStartActivityLocked方法真正启动activity
if (realStartActivityLocked(hr, app, true, true)) {
didSomething = true;
}
} catch (RemoteException e) {
Slog.w(TAG, "Exception in new application when starting activity "
+ hr.intent.getComponent().flattenToShortString(), e);
throw e;
}
}
}
}
}
if (!didSomething) {
ensureActivitiesVisibleLocked(null, 0);
}
return didSomething;
}
紧接着调用ActivityStackSupervisor的realStartActivityLocked方法真正启动activity:
final boolean realStartActivityLocked(ActivityRecord r,
ProcessRecord app, boolean andResume, boolean checkConfig)
throws RemoteException {
......
try {
......
app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
new Configuration(stack.mOverrideConfig), r.compat, r.launchedFromPackage,
task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,
newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);
......
} catch (RemoteException e) {
......
}
......
return true;
}
看到这里应该很熟悉,和Application的启动一样,通过binder跨进程提调用到应用进程ApplicationThread的scheduleLaunchActivity方法中:
@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();
r.token = token;
r.ident = ident;
r.intent = intent;
r.referrer = referrer;
r.voiceInteractor = voiceInteractor;
r.activityInfo = info;
r.compatInfo = compatInfo;
r.state = state;
r.persistentState = persistentState;
r.pendingResults = pendingResults;
r.pendingIntents = pendingNewIntents;
r.startsNotResumed = notResumed;
r.isForward = isForward;
r.profilerInfo = profilerInfo;
r.overrideConfig = overrideConfig;
updatePendingConfiguration(curConfig);
//将消息交给H类型的mH处理
sendMessage(H.LAUNCH_ACTIVITY, r);
}
通过H类型的mH将标识为LAUNCH_ACTIVITY传递给mH处理:
public void handleMessage(Message msg) {
......
switch (msg.what) {
case LAUNCH_ACTIVITY: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
r.packageInfo = getPackageInfoNoCheck(
r.activityInfo.applicationInfo, r.compatInfo);
handleLaunchActivity(r, null);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
} break;
......
case BIND_APPLICATION:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
AppBindData data = (AppBindData)msg.obj;
handleBindApplication(data);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
......
}
......
}
然后调用了ActivityThread的handleLaunchActivity方法:
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
......
//1.执行Activity的初始化及oncreate方法
Activity a = performLaunchActivity(r, customIntent);
if (a != null) {
......
//2.执行Activity的onResume方法
handleResumeActivity(r.token, false, r.isForward,
!r.activity.mFinished && !r.startsNotResumed);
......
} else {
......
}
}
先分析注释1处,看看activity的oncreate方法如何执行的,ActivityThread的performLaunchActivity方法:
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
......
Activity activity = null;
try {
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
//1.创建activity
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
StrictMode.incrementExpectedActivityCount(activity.getClass());
r.intent.setExtrasClassLoader(cl);
r.intent.prepareToEnterProcess();
if (r.state != null) {
r.state.setClassLoader(cl);
}
} catch (Exception e) {
if (!mInstrumentation.onException(activity, e)) {
throw new RuntimeException(
"Unable to instantiate activity " + component
+ ": " + e.toString(), e);
}
}
try {
//2.创建Application,实质上Application已经创建,只是获得已有的Application 实例
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
......
if (activity != null) {
//3.创建context
Context appContext = createBaseContextForActivity(r, activity);
......
//4.将Context和Application 与activity关联起来,完成activity的初始化
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config,
r.referrer, r.voiceInteractor);
//5.调用activity的oncreate方法
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
......
if (!r.activity.mFinished) {
//6.调用activity的onStart方法
activity.performStart();
r.stopped = false;
}
if (!r.activity.mFinished) {
if (r.isPersistable()) {
if (r.state != null || r.persistentState != null) {
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
r.persistentState);
}
} else if (r.state != null) {
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
}
}
......
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) {
if (!mInstrumentation.onException(activity, e)) {
throw new RuntimeException(
"Unable to start activity " + component
+ ": " + e.toString(), e);
}
}
return activity;
}
这段代码有6处注释,我们来一一分析:注释1处,同创建Application一样通过反射创建一个Activity 实例。注释2处:之前分析过一个应用程序,如果已经存在一个Application实例,则不再创建新的实例,直接返回以前的Application实例。注释3处创建一个activity初始化所需要的context。注释4处,通过Activity的attach方法完成Context和Application 与activity关联,同时activity的初始化,这里由于篇幅原因就不再继续分析attach方法的具体实现了。注释5处,会调用activity的oncreate方法,6处会调用ctivity的onStart方法。接下来分别分析注释5与6两处,以便搞清楚,activity的oncreate与onStart是怎么被回调的。
Instrumentation的callActivityOnCreate方法:
public void callActivityOnCreate(Activity activity, Bundle icicle) {
prePerformCreate(activity);
activity.performCreate(icicle);
postPerformCreate(activity);
}
直接看activity的performCreate方法:
final void performCreate(Bundle icicle) {
onCreate(icicle);
mActivityTransitionState.readState(icicle);
performCreateCommon();
}
再然后就调用到了我们熟悉的activity的onCreate方法中。
分析完了activity的onCreate,我们再来看activity的performStart方法:
final void performStart() {
......
mInstrumentation.callActivityOnStart(this);
......
}
和oncreate方法一样,通过Instrumentation控制activity的onStart方法,调用Instrumentation的callActivityOnStart方法:
public void callActivityOnStart(Activity activity) {
activity.onStart();
}
直接调用了activity的onStart方法。
这样就分析完了ActivityThread的handleLaunchActivity方法的注释1处,下面再来分析注释2处:
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
......
//1.执行Activity的初始化及oncreate方法
Activity a = performLaunchActivity(r, customIntent);
if (a != null) {
......
//2.执行Activity的onResume方法
handleResumeActivity(r.token, false, r.isForward,
!r.activity.mFinished && !r.startsNotResumed);
......
} else {
......
}
}
注释2处调用了ActivityThread的handleResumeActivity方法:
final void handleResumeActivity(IBinder token,
boolean clearHide, boolean isForward, boolean reallyResume) {
......
ActivityClientRecord r = performResumeActivity(token, clearHide);
......
}
接着调用了ActivityThread的performResumeActivity方法:
public final ActivityClientRecord performResumeActivity(IBinder token,
boolean clearHide) {
......
if (r != null && !r.activity.mFinished) {
if (clearHide) {
r.hideForNow = false;
r.activity.mStartedActivity = false;
}
try {
......
//调用activity的performResume方法
r.activity.performResume();
......
} catch (Exception e) {
if (!mInstrumentation.onException(r.activity, e)) {
throw new RuntimeException(
"Unable to resume activity "
+ r.intent.getComponent().toShortString()
+ ": " + e.toString(), e);
}
}
}
return r;
}
然后调用了activity的performResume方法:
final void performResume() {
......
mInstrumentation.callActivityOnResume(this);
......
}
同上文执行activity的onCreate和onStart方法一样。通过Instrumentation控制activity的生命周期方法。接着调用Instrumentation的callActivityOnResume方法:
public void callActivityOnResume(Activity activity) {
activity.mResumed = true;
activity.onResume();
......
}
然后就调用了activity的onResume()方法。
这样acticity启动过程中的几个生命周期方法就大概的分析完了,主要说明了他们是怎么执行的,但是还是省略了一些细节,比如activity的初始化的一些操作,比如activity的onResume方法是怎样让布局显示在界面上的等等,以后的文章会详细分析这个过程的。
3.总结
这篇文章从ActivityThread的main方法开始,分析了application如何创建及oncreate方法何时被会调的和一些activity启动相关的生命周期方法。