Activity启动详细流程(下)
四. 新进程启动ActivityThread
- Zygote进程孵化出新的应用进程后,会执行ActivityThread类的main方法。
- 在该方法里会先准备好Looper和消息队列,然后调用attach方法将应用进程绑定到ActivityManagerService。
然后进入loop循环,不断地读取消息队列里的消息,并分发消息。
//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(); //... }
五. 应用进程绑定到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
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
方法。//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处理启动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; }
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 { //... } }
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
的实例,并执行它的生命周期方法.
- 用户在Launcher程序里点击应用图标时,会通知
现在也可以理解:
- 如果应用的组件(包括所有组件Activity,Service,ContentProvider,Receiver) 被启动,肯定会先启动以应用包名为进程名的进程,这些组件都会运行在应用包名为进程名的进程里,并且是在主线程里。
- 应用进程启动时会先创建
Application
对象,并执行Application
对象的生命周期方法,然后才启动应用的组件。
有一种情况比较特殊,那就是为组件设置了特殊的进程名,也就是说通过
android:process
设置进程名的情况,此时组件运行在单独的进程内。