本系列博客將詳細闡述Activity的啟動流程,這些博客基于Cm 10.1源碼研究。
深入理解Activity啟動流程(一)--Activity啟動的概要流程深入理解Activity啟動流程(二)--Activity啟動相關類的類圖深入理解Activity啟動流程(三)--Activity啟動的詳細流程1深入理解Activity啟動流程(四)--Activity Task的調度算法上篇博客介紹了Activity詳細啟動流程的前半部分:
1. Activity調用ActivityManagerService啟動應用2. ActivityManagerService調用Zygote孵化應用進程3. Zygote孵化應用進程本篇博客主要介紹Activity詳細啟動流程的后半部分:
4. 新進程啟動ActivityThread5. 應用進程綁定到ActivityManagerService6. ActivityThread的Handler處理啟動Activity的消息點擊圖片可看大圖

Zygote進程孵化出新的應用進程后,會執行ActivityThread類的main方法。在該方法里會先準備好Looper和消息隊列,然后調用attach方法將應用進程綁定到ActivityManagerService,然后進入loop循環,不斷地讀取消息隊列里的消息,并分發消息。
12345678910111213141516 | //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(); //...} |
點擊圖片可看大圖

在ActivityThread的main方法里調用thread.attach(false);attach方法的主要代碼如下所示:
123456789101112131415161718192021 | //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)進行綁定。
1234567891011121314151617181920212223242526272829303132333435363738394041 | //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對象其實是ActivityThread里ApplicationThread對象在ActivityManagerService的代理對象,故此執行thread.bindApplication,最終會調用ApplicationThread的bindApplication方法,該方法的主要代碼如下所示:
12345678910111213141516171819202122232425262728 | //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方法處理綁定消息。
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849 | //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); }} |
realStartActivity會調用scheduleLaunchActivity啟動activity,主要代碼:
1234567891011121314151617181920212223 | //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方法。
1234567891011121314151617181920212223 | //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便會處理該消息。
點擊圖片可看大圖

ActivityThread的handler調用handleLaunchActivity處理啟動Activity的消息,handleLaunchActivity的主要代碼如下所示:
12345678910111213 | //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的主要代碼如下所示:
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455 | //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;} |
handleResumeActivity的主要代碼如下所示:
123456789101112131415161718192021222324252627282930313233343536373839 | //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 { //... }} |
performResumeActivity的主要代碼如下所示:
123456789101112131415161718 | //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的實例,并執行它的生命周期方法
現在也可以理解:
如果應用的組件(包括所有組件Activity,Service,ContentProvider,Receiver) 被啟動,肯定會先啟動以應用包名為進程名的進程,這些組件都會運行在應用包名為進程名的進程里,并且是在主線程里。應用進程啟動時會先創建Application對象,并執行Application對象的生命周期方法,然后才啟動應用的組件。
有一種情況比較特殊,那就是為組件設置了特殊的進程名,也就是說通過android:process設置進程名的情況,此時組件運行在單獨的進程內。
下篇博客將介紹Activity,Task的調度算法。
新聞熱點
疑難解答