上篇部落格介紹了Activity詳細啟動流程的前半部分:
1. Activity調用ActivityManagerService啟動應用
2. ActivityManagerService調用Zygote孵化應用程序
3. Zygote孵化應用程序
本篇部落客要介紹Activity詳細啟動流程的後半部分:
4. 新程序啟動ActivityThread
5. 應用程序綁定到ActivityManagerService
6. ActivityThread的Handler處理啟動Activity的消息
4. 新程序啟動ActivityThread
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyMxETMyEzM5AzMxMDM4EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
第一步:ActivityThread的main方法
//ActivityThread類
public static void main(String[] args) {
//...
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
AsyncTask.init();
//...
Looper.loop();
//...
}
Zygote程序孵化出新的應用程序後,會執行ActivityThread類的main方法。在該方法裡會先準備好Looper和消息隊列,然後調用attach方法将應用程序綁定到ActivityManagerService,然後進入loop循環,不斷地讀取消息隊列裡的消息,并分發消息。
5. 應用程序綁定到ActivityManagerService
第二步:在ActivityThread的main方法裡調用thread.attach(false);attach方法的主要代碼如下所示:
//ActivityThread類
private void attach(boolean system) {
sThreadLocal.set(this);
mSystemThread = system;
if (!system) {
//...
IActivityManager mgr = ActivityManagerNative.getDefault();
try {
//調用ActivityManagerService的attachApplication方法
//将ApplicationThread對象綁定至ActivityManagerService,
//這樣ActivityManagerService就可以
//通過ApplicationThread代理對象控制應用程序
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
// Ignore
}
} else {
//...
}
//...
}
第三步:ActivityManagerService的attachApplication方法執行attachApplicationLocked(thread, callingPid)進行綁定
//ActivityManagerService類
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid) {
ProcessRecord app;
//...
app.thread = thread;
//...
try {
//...
thread.bindApplication(processName, appInfo, providers,
app.instrumentationClass, profileFile, profileFd, profileAutoStop,
app.instrumentationArguments, app.instrumentationWatcher, testMode,
enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
mCoreSettingsObserver.getCoreSettingsLocked());
//...
} catch (Exception e) {
//...
}
//...
ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
if (hr != null && normalMode) {
if (hr.app == null && app.uid == hr.info.applicationInfo.uid
&& processName.equals(hr.processName)) {
try {
if (mHeadless) {
Slog.e(TAG, "Starting activities not supported on headless device: " + hr);
} else if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
//mMainStack.realStartActivityLocked真正啟動activity
didSomething = true;
}
} catch (Exception e) {
//...
}
} else {
//...
}
}
//...
return true;
}
attachApplicationLocked方法有兩個重要的函數調用thread.bindApplication和mMainStack.realStartActivityLocked。thread.bindApplication将應用程序的ApplicationThread對象綁定到ActivityManagerService,也就是說獲得ApplicationThread對象的代理對象。mMainStack.realStartActivityLocked通知應用程序啟動Activity。
第四步:thread.bindApplication
thread對象其實是ActivityThread裡ApplicationThread對象在ActivityManagerService的代理對象,故此執行thread.bindApplication,最終會調用ApplicationThread的bindApplication方法,該方法的主要代碼如下所示:
//ActivityThread類
public final void bindApplication(String processName,
ApplicationInfo appInfo, List<ProviderInfo> providers,
ComponentName instrumentationName, String profileFile,
ParcelFileDescriptor profileFd, boolean autoStopProfiler,
Bundle instrumentationArgs, IInstrumentationWatcher instrumentationWatcher,
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.debugMode = debugMode;
data.enableOpenGlTrace = enableOpenGlTrace;
data.restrictedBackupMode = isRestrictedBackupMode;
data.persistent = persistent;
data.config = config;
data.compatInfo = compatInfo;
data.initProfileFile = profileFile;
data.initProfileFd = profileFd;
data.initAutoStopProfiler = false;
queueOrSendMessage(H.BIND_APPLICATION, data);
}
這樣調用queueOrSendMessage會往ActivityThread的消息隊列發送消息,消息的用途是BIND_APPLICATION。
第五步:這樣會在handler裡處理BIND_APPLICATION消息,接着調用handleBindApplication方法處理綁定消息
//ActivityThread類
private void handleBindApplication(AppBindData data) {
//...
ApplicationInfo instrApp = new ApplicationInfo();
instrApp.packageName = ii.packageName;
instrApp.sourceDir = ii.sourceDir;
instrApp.publicSourceDir = ii.publicSourceDir;
instrApp.dataDir = ii.dataDir;
instrApp.nativeLibraryDir = ii.nativeLibraryDir;
LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
appContext.getClassLoader(), false, true);
ContextImpl instrContext = new ContextImpl();
instrContext.init(pi, null, this);
//...
if (data.instrumentationName != null) {
//...
} else {
//注意Activity的所有生命周期方法都會被Instrumentation對象所監控,
//也就說執行Activity的生命周期方法前後一定會調用Instrumentation對象的相關方法
//并不是說隻有跑單測用例才會建立Instrumentation對象,
//即使不跑單測也會建立Instrumentation對象
mInstrumentation = new Instrumentation();
}
//...
try {
//...
Application app = data.info.makeApplication(data.restrictedBackupMode, null);
mInitialApplication = app;
//...
try {
mInstrumentation.onCreate(data.instrumentationArgs);
}catch (Exception e) {
//...
}
try {
//這裡會調用Application的onCreate方法
//故此Applcation對象的onCreate方法會比ActivityThread的main方法後調用
//但是會比這個應用的所有activity先調用
mInstrumentation.callApplicationOnCreate(app);
} catch (Exception e) {
//...
}
} finally {
StrictMode.setThreadPolicy(savedPolicy);
}
}
第六步:mMainStack.realStartActivityLocked
ActivityStack的realStartActivity方法會調用scheduleLaunchActivity啟動activity,主要代碼:
//ActivityStack類
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),
r.compat, r.icicle, results, newIntents, !andResume,
mService.isNextTransitionForward(), profileFile, profileFd,
profileAutoStop);
//...
} catch (RemoteException e) {
//...
}
//...
return true;
}
同樣app.thread也隻是ApplicationThread對象在ActivityManagerService的一個代理對象而已,最終會調用ApplicationThread的scheduleLaunchActivity方法。
第七步:ApplicationThread的scheduleLaunchActivity方法
//ActivityThread類
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
Bundle state, List<ResultInfo> pendingResults,
List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
ActivityClientRecord r = new ActivityClientRecord();
r.token = token;
r.ident = ident;
r.intent = intent;
r.activityInfo = info;
r.compatInfo = compatInfo;
r.state = state;
r.pendingResults = pendingResults;
r.pendingIntents = pendingNewIntents;
r.startsNotResumed = notResumed;
r.isForward = isForward;
r.profileFile = profileName;
r.profileFd = profileFd;
r.autoStopProfiler = autoStopProfiler;
updatePendingConfiguration(curConfig);
queueOrSendMessage(H.LAUNCH_ACTIVITY, r);
}
這裡調用了queueOrSendMessage往ActivityThread的消息隊列發送了消息,消息的用途是啟動Activity,接下來ActivityThread的handler便會處理該消息。
6. ActivityThread的Handler處理啟動Activity的消息
ActivityThread的handler調用handleLaunchActivity處理啟動Activity的消息,
第八步:handleLaunchActivity
//ActivityThread類
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
//...
Activity a = performLaunchActivity(r, customIntent);
if (a != null) {
//...
handleResumeActivity(r.token, false, r.isForward,
!r.activity.mFinished && !r.startsNotResumed);
//...
} else {
//...
}
}
handleLaunchActivity方法裡有有兩個重要的函數調用,performLaunchActivity和handleResumeActivity,performLaunchActivity會調用Activity的onCreate,onStart,onResotreInstanceState方法,handleResumeActivity會調用Activity的onResume方法.
第九步: performLaunchActivity
//ActivityThread類
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
//...
Activity activity = null;
try {
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
//...
} catch (Exception e) {
//...
}
try {
//r.packageInfo.makeApplication實際并未建立Application對象,
//因為bindApplication過程已經建立了Application對象,
//makeApplication方法會傳回已建立的Application對象
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
//...
if (activity != null) {
//...
//将application對象,appContext對象綁定到建立的activity對象
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config);
//...
//會調用Activity的onCreate方法
mInstrumentation.callActivityOnCreate(activity, r.state);
//...
//...
//調用Activity的onStart方法
if (!r.activity.mFinished) {
activity.performStart();
r.stopped = false;
}
if (!r.activity.mFinished) {
if (r.state != null) {
//會調用Activity的onRestoreInstanceState方法
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
}
}
if (!r.activity.mFinished) {
activity.mCalled = false;
mInstrumentation.callActivityOnPostCreate(activity, r.state);
//...
}
}
//...
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) {
//...
}
return activity;
}
performLaunchActivity會調用Activity的onCreate,onStart,onResotreInstanceState方法。
第十步: handleResumeActivity
//ActivityThread類
final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward,
boolean reallyResume) {
//...
//performResumeActivity最終會調用Activity的onResume方法
ActivityClientRecord r = performResumeActivity(token, clearHide);
if (r != null) {
final Activity a = r.activity;
//...
//顯示界面
if (r.window == null && !a.mFinished && willBeVisible) {
r.window = r.activity.getWindow();
View decor = r.window.getDecorView();
decor.setVisibility(View.INVISIBLE);
ViewManager wm = a.getWindowManager();
WindowManager.LayoutParams l = r.window.getAttributes();
a.mDecor = decor;
l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
l.softInputMode |= forwardBit;
if (a.mVisibleFromClient) {
a.mWindowAdded = true;
wm.addView(decor, l);
}
//...
} else if (!willBeVisible) {
//...
}
// Tell the activity manager we have resumed.
if (reallyResume) {
try {
ActivityManagerNative.getDefault().activityResumed(token);
} catch (RemoteException ex) {
}
}
} else {
//...
}
}
handleResumeActivity會調用performResumeActivity方法,最後會調用Activity的onResume方法。
第十一步:performResumeActivity
//ActivityThread類
public final ActivityClientRecord performResumeActivity(IBinder token,
boolean clearHide) {
ActivityClientRecord r = mActivities.get(token);
//...
if (r != null && !r.activity.mFinished) {
//...
try {
//...
//會調用Activity的onResume方法
r.activity.performResume();
//...
} catch (Exception e) {
//...
}
}
return r;
}
總結
Activity的概要啟動流程:
使用者在Launcher程式裡點選應用圖示時,會通知ActivityManagerService啟動應用的入口Activity,ActivityManagerService發現這個應用還未啟動,則會通知Zygote程序孵化出應用程序,然後在這個dalvik應用程序裡執行ActivityThread的main方法。應用程序接下來通知ActivityManagerService應用程序已啟動,ActivityManagerService儲存應用程序的一個代理對象,這樣ActivityManagerService可以通過這個代理對象控制應用程序,然後ActivityManagerService通知應用程序建立入口Activity的執行個體,并執行它的生命周期方法。