上海建设网站的公司网站建设网站
跟踪Activity启动流程
基于 Android8.0 源码跟踪
Android8/9大同小异,但Android10对activity的管理解耦交给了ATMS。
跟踪目的:ams到底在哪里发起activity的启动的?以及resume等生命周期到底是谁发起的?onResume()之后是哪里发起的界面绘制?
下次任务:
- activity栈管理
- wms、handler与同步屏障、屏幕刷新机制
ZygoteInit
孵化器首先fork一个systemserver,然后进入循环,监听fork需求。
public static void main(String argv[]) {if (startSystemServer) {Runnable r = forkSystemServer(abiList, socketName, zygoteServer);if (r != null) {r.run();return;}}caller = zygoteServer.runSelectLoop(abiList);} catch (Throwable ex) {Log.e(TAG, "System zygote died with exception", ex);throw ex;} finally {zygoteServer.closeServerSocket();}if (caller != null) {caller.run();}
}
fork后的进程进入r.run()或者caller.run(),并退出socket监听,原本的zygote进程,仍然保持在loop()状态。
ZygoteServer
通过socekt连接与监听
Runnable runSelectLoop(String abiList) {while (true) {ZygoteConnection connection = peers.get(i);final Runnable command = connection.processOneCommand(this);}
}
ZygoteConnection
真的在socket监听,同时fork出进程来
Runnable processOneCommand(ZygoteServer zygoteServer) {//socket阻塞获取消息args = readArgumentList();//forkpid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,parsedArgs.niceName, fdsToClose, fdsToIgnore, parsedArgs.instructionSet,parsedArgs.appDataDir);//fork返回到两个进程try {//如果pid为0,说明当前返回到子进程if (pid == 0) {// in childzygoteServer.setForkChild();zygoteServer.closeServerSocket();IoUtils.closeQuietly(serverPipeFd);serverPipeFd = null;return handleChildProc(parsedArgs, descriptors, childPipeFd);} else {//回到zygote进程IoUtils.closeQuietly(childPipeFd);childPipeFd = null;handleParentProc(pid, descriptors, serverPipeFd);return null;}} finally {IoUtils.closeQuietly(childPipeFd);IoUtils.closeQuietly(serverPipeFd);}}
如果回到子进程,将会关掉zygoteServer等,并将子进程返回出去。看一下handleChildProc(),在这里会关掉socket,并且
private Runnable handleChildProc(Arguments parsedArgs, FileDescriptor[] descriptors,FileDescriptor pipeFd) {//关闭socketcloseSocket();//zogyteInit去反射子进程的mainreturn ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs,null /* classLoader */);
}
回到zygoteInit,看一下zygoteInit如何返回一个子进程,通过run()来启动子进程
ZygoteInit
public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {if (RuntimeInit.DEBUG) {Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");}Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");RuntimeInit.redirectLogStreams();RuntimeInit.commonInit();//初始胡运行环境ZygoteInit.nativeZygoteInit();//启动Binde线程池进程return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}private static final native void nativeZygoteInit();
在这里面,通过jni进入AndroidRuntime.cpp,启动binder线程:
AndroidRuntime.cpp
static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{gCurRuntime->onZygoteInit();
}
然后进入到app_main.cpp中进行ProcessState的初始化,以及打开binder线程池等待监听数据。
app_main.cpp
virtual void onZygoteInit()
{sp<ProcessState> proc = ProcessState::self();ALOGV("App process: starting thread pool.\n");proc->startThreadPool();
}
细节不再描述了,在binder中追踪过这部分代码。回到zygoteInit,最后RuntimeInit.applicationInit();来启动应用程序
RuntimeInit
protected static Runnable applicationInit(int targetSdkVersion, String[] argv,ClassLoader classLoader) {return findStaticMain(args.startClass, args.startArgs, classLoader);
}
反射获取到了 ActivityThread.main(),并封装进一个 Runnable中执行
ActivityThread
- 首先准备Looper
- 然后打开applicationThread,这是一个binder线程
- 通知ams我的main()运行了,你可以通知我开启activity了
public static void main(String[] args) {Looper.prepareMainLooper();ActivityThread thread = new ActivityThread();thread.attach(false);//这是核心if (sMainThreadHandler == null) {sMainThreadHandler = thread.getHandler();//拿到的是mH}Looper.loop();
}
看到attach()方法
private void attach(boolean system) {sCurrentActivityThread = this;mSystemThread = system;if (!system) {ViewRootImpl.addFirstDrawHandler();RuntimeInit.setApplicationObject(mAppThread.asBinder());final IActivityManager mgr = ActivityManager.getService();try {//将自己的binder线程,也就是applicationThread,只要不是系统服务,就会暴露给ams,交给它管理自己。即便是我们自己写的service,也是进入到这里,不要和系统服务搞混了mgr.attachApplication(mAppThread);} catch (RemoteException ex) {throw ex.rethrowFromSystemServer();}}else{//...}ViewRootImpl.ConfigChangedCallback configChangedCallback = something;ViewRootImpl.addConfigCallback(configChangedCallback);
}
然后我们就去ams中看看attachApplication做了什么
ActivityManagerService
public final void attachApplication(IApplicationThread thread) {synchronized (this) {int callingPid = Binder.getCallingPid();final long origId = Binder.clearCallingIdentity();attachApplicationLocked(thread, callingPid);Binder.restoreCallingIdentity(origId);}
}
进入到attachApplicationLocked,我们只关注什么时候发起activity启动通知。
我们发现,首先通过IPC通信,让APP先进行bindApplication,然后才到 ActivityStackSupervisor来通知启动activity
private final boolean attachApplicationLocked(IApplicationThread thread,int pid) {ProcessRecord app;//contentproviderList<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;if (providers != null && checkAppInLaunchingProvidersLocked(app)) {Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);msg.obj = app;mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);}//...if (app.instr != null) {thread.bindApplication();} else {thread.bindApplication();}//activity栈管理if (normalMode) {try {//通知activity栈管理者,我开了application了,后续你看着办(把任务交给了stack管理者if (mStackSupervisor.attachApplicationLocked(app)) {didSomething = true;}} catch (Exception e) {Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);badApp = true;}}//一些对service、broadcast等的检查return true;
}
在开启activity之前,需要先对application做一个启动处理,application的启动应当在contentprovider之后,activity,service,receiver之前。这里的IApplicationThread是一个aidl,也就是远程服务。我们知道他是一个binder实体。其实就是通过binderproxy来远程IPC调用到app进程的applicationThread的方法:
ApplicationThread in ActivityThread
果然,这个ApplicationThread是一个binder实体,也就是Stub。我们关注到bindApplication方法:
private class ApplicationThread extends IApplicationThread.Stub {public final void bindApplication() {//一系列的参数设置AppBindData data = new AppBindData();data.processName = processName;data.appInfo = appInfo;data.providers = providers;data.instrumentationName = instrumentationName;data.instrumentationArgs = instrumentationArgs;//...data.buildSerial = buildSerial;//最后通过handler通知给mHsendMessage(H.BIND_APPLICATION, data);// mH.sendMessage(msg);}
}
我们关注到mH处理这个 BIND_APPLICATION 消息,在mH的handleMessage的switch case分支中,是这样的
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;
handleBindApplication()方法特别长,我们看重点:
private void handleBindApplication(AppBindData data) {//版本检查if (data.appInfo.targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB) {StrictMode.enableDeathOnNetwork();}if (data.appInfo.targetSdkVersion >= Build.VERSION_CODES.N) {StrictMode.enableDeathOnFileUriExposure();}//开启HttpProxy等操作。。。//创建上下文final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);updateLocaleListFromAppContext(appContext,mResourcesManager.getConfiguration().getLocales());// 反射获取Instrumentation,用来调度四大组件if (ii != null) {final ApplicationInfo instrApp = new ApplicationInfo();ii.copyTo(instrApp);instrApp.initForUser(UserHandle.myUserId());final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,appContext.getClassLoader(), false, true, false);final ContextImpl instrContext = ContextImpl.createAppContext(this, pi);try {//获取到Instrumentationfinal ClassLoader cl = instrContext.getClassLoader();mInstrumentation = (Instrumentation)cl.loadClass(data.instrumentationName.getClassName()).newInstance();} catch (Exception e) {throw new RuntimeException("Unable to instantiate instrumentation "+ data.instrumentationName + ": " + e.toString(), e);}//组件名final ComponentName component = new ComponentName(ii.packageName, ii.name);mInstrumentation.init(this, instrContext, appContext, component,data.instrumentationWatcher, data.instrumentationUiAutomationConnection);} else {mInstrumentation = new Instrumentation();}//开始进入生命周期,首先开启contentprovider,然后开启application.onCreate()!!!Application app;try {mInitialApplication = app;//开启contentproviderinstallContentProviders(app, data.providers);//Instrumentation的oncreatemInstrumentation.onCreate(data.instrumentationArgs);//application的onCreate()回调mInstrumentation.callApplicationOnCreate(app);} finally {//...}// 预加载文字资源。。
}
看完Application的初始化,我们回到AMS,它接着又通知了 ActivityStackSupervisor.attachApplicationLocked().
整个Android系统的Activity都被AMS管理(Android10之后ATM管理),但最终activity的栈管理,都是交给ActivityStackSupervisor来做的。在栈中,所有Activity都以ActivityRecord的形式存在。
其中真正启动activity的语句是:realStartActivityLocked()
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 (!isFocusedStack(stack)) {continue;}stack.getAllRunningVisibleActivitiesLocked(mTmpActivityList);final ActivityRecord top = stack.topRunningActivityLocked();final int size = mTmpActivityList.size();for (int i = 0; i < size; i++) {final ActivityRecord activity = mTmpActivityList.get(i);if (activity.app == null && app.uid == activity.info.applicationInfo.uid&& processName.equals(activity.processName)) {try {//开启activityif (realStartActivityLocked(activity, app,top == activity /* andResume */, true /* checkConfig */)) {didSomething = true;}} catch (RemoteException e) {Slog.w(TAG, "Exception in new application when starting activity "+ top.intent.getComponent().flattenToShortString(), e);throw e;}}}}}if (!didSomething) {ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);}return didSomething;
}
我们进入到 realStartActivityLocked来看看怎么启动的activity
ActivityStackSupervisor
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,boolean andResume, boolean checkConfig) throws RemoteException {try {r.startFreezingScreenLocked(app, 0);// schedule launch ticks to collect information about slow apps.r.startLaunchTickingLocked();r.app = app;//app进程,记录其activity集合//在ProcessRecord中,是这样的:final ArrayList<ActivityRecord> activities = new ArrayList<>();int idx = app.activities.indexOf(r);if (idx < 0) {app.activities.add(r);}try {//如果activity本就有,那么就通过newIntentif (andResume) {results = r.results;newIntents = r.newIntents;}//如果这是个HomeActivity,也就是<Main>if (r.isHomeActivity()) {// Home process is the root process of the task.mService.mHomeProcess = task.mActivities.get(0).app;};//这里真正的发起了 Activity的启动app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,System.identityHashCode(r), r.info,// TODO: Have this take the merged configuration instead of separate global// and override configs.mergedConfiguration.getGlobalConfiguration(),mergedConfiguration.getOverrideConfiguration(), r.compat,r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,r.persistentState, results, newIntents, !andResume,mService.isNextTransitionForward(), profilerInfo);} catch (RemoteException e) {if (r.launchFailed) {//如果启动出错了,结束activitystack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,"2nd-crash", false);return false;}//从集合中去除掉r.launchFailed = true;app.activities.remove(r);throw e;}} r.launchFailed = false;//oncreate后紧接着进行start、resumeif (andResume && readyToResume()) {// As part of the process of launching, ActivityThread also performs// a resume.stack.minimalResumeActivityLocked(r);} return true;
}
我们看到了熟悉的:scheduleLaunchActivity()
,我们看看它是不是发起了activity.onCreate(),同时我们找找onStart、onResume在哪里发起。ActivityStackSupervisor也是通过 IApplicationThread 这个 binder引用远程通知app进程的。也就是通过binder发起transaction(事务)。我们回到ApplicationThread,看一下是怎么处理这个事务的。
ApplicationThread in ActivityThread
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) {ActivityClientRecord r = new ActivityClientRecord();//设置一些从ams传递来的消息//通知主线程的mHsendMessage(H.LAUNCH_ACTIVITY, r);
}
ActivityThread的mH就会处理这个 LAUNCH_ACTIVITY 的事件:
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, "LAUNCH_ACTIVITY");Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);} break;
接下来就进入了最最最亲切的 handleLaunchActivity():
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {//这里初始化了windowManagerGlobal,这和WMS有关系WindowManagerGlobal.initialize();//真正的发起activity启动Activity a = performLaunchActivity(r, customIntent);//onCreate之后,如果启动成功,就继续进入onStart和onResumeif (a != null) {r.createdConfig = new Configuration(mConfiguration);reportSizeConfigurations(r);Bundle oldState = r.state;handleResumeActivity(r.token, false, r.isForward,!r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);if (!r.activity.mFinished && r.startsNotResumed) {//如果过程出错了,就进入onPauseperformPauseActivityIfNeeded(r, reason);if (r.isPreHoneycomb()) {r.state = oldState;}}} else {//如果启动activity失败,通知ams去finishactivity,即处理activity栈相关工作try {ActivityManager.getService().finishActivity(r.token, Activity.RESULT_CANCELED, null,Activity.DONT_FINISH_TASK_WITH_ACTIVITY);} catch (RemoteException ex) {throw ex.rethrowFromSystemServer();}}
}
我们看到这,发现首先performLaunchActivity()应当是调用onCreate(),如果没问题,接下来就会紧接着handleResumeActivity(),我们接下来就要看,onStart()是在哪个方法里面调用的。我们先看到performLaunchActivity()
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {ActivityInfo aInfo = r.activityInfo;//获取组件名ComponentName component = r.intent.getComponent();if (component == null) {component = r.intent.resolveActivity(mInitialApplication.getPackageManager());r.intent.setComponent(component);}if (r.activityInfo.targetActivity != null) {component = new ComponentName(r.activityInfo.packageName,r.activityInfo.targetActivity);}//为activity创建一个contextContextImpl appContext = createBaseContextForActivity(r);Activity activity = null;try {//反射new一个Activity实例出来java.lang.ClassLoader cl = appContext.getClassLoader();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);}}//有了activity实例之后try {Application app = r.packageInfo.makeApplication(false, mInstrumentation);//做一些设置if (activity != null) {//windowWindow window = null;if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {window = r.mPendingRemoveWindow;r.mPendingRemoveWindow = null;r.mPendingRemoveWindowManager = null;}//在这里,处理了activity和window、windowmanagerservice的关系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, window, r.configCallback);//如果有intent,交给activity,后面可以通过getIntent()获取//我们发现intent经过了IPC,所以这也表明intent的数据需要是Parcel的,而且不能过大if (customIntent != null) {activity.mIntent = customIntent;}activity.mStartedActivity = false;//设置主题int theme = r.activityInfo.getThemeResource();if (theme != 0) {activity.setTheme(theme);}//在这里调用了 activity.onCreate()if (r.isPersistable()) {mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);} else {mInstrumentation.callActivityOnCreate(activity, r.state);}//紧接着,调用onStart()r.activity = activity;r.stopped = true;if (!r.activity.mFinished) {activity.performStart();r.stopped = false;}//将activity原有状态进行恢复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);}}if (!r.activity.mFinished) {activity.mCalled = false;if (r.isPersistable()) {mInstrumentation.callActivityOnPostCreate(activity, r.state,r.persistentState);} else {mInstrumentation.callActivityOnPostCreate(activity, r.state);}if (!activity.mCalled) {throw new SuperNotCalledException("Activity " + r.intent.getComponent().toShortString() +" did not call through to super.onPostCreate()");}}}r.paused = true;mActivities.put(r.token, r);} 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;
}
我们发现,在performLaunchActivity()中,除了调用Activity的onCreate(),还调用了 Activity的onStart()。都是通过 Instrumentation。(我们还会发现Activity的所有生命周期都由Instrumentation发起,所以我们可以通过Instrumentation来hook所有Activity的生命周期)
现在进度就明朗了,接下来就是handleLaunchActivity()中的performResumeActivity()了。我们来看一下他做了什么,之前有一个window出现了,但是还没给他赋值,会在这里完成这个工作吗?因为我们知道onResume()之后,界面就绘制出来了,所以我们接下来的重点不再是追踪onResume()而是来看看界面的绘制是在哪里开始的:
final void handleResumeActivity(IBinder token,boolean clearHide, boolean isForward, boolean reallyResume, int seq, String reason) {ActivityClientRecord r = mActivities.get(token);//调用onResume()r = performResumeActivity(token, clearHide, reason);if (r != null) {final Activity a = r.activity;final int forwardBit = isForward ?WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION : 0;// If the window hasn't yet been added to the window manager,// and this guy didn't finish itself or start another activity,// then go ahead and add the window.boolean willBeVisible = !a.mStartedActivity;if (!willBeVisible) {try {willBeVisible = ActivityManager.getService().willActivityBeVisible(a.getActivityToken());} catch (RemoteException e) {throw e.rethrowFromSystemServer();}}//如果这个activity不为空,也没结束,但是它的window是空的,换句话说,在onCreate()中并没有进行setContentView(),就会进入到下面的内容。//这里面的几步,本来应该是 setContentView()做得,但是由于之前没有调用setContentView,所以到这里来进行默认处理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();//1. 主动地为activity设置一个decorviewa.mDecor = decor;l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;l.softInputMode |= forwardBit;if (r.mPreserveWindow) {a.mWindowAdded = true;r.mPreserveWindow = false;ViewRootImpl impl = decor.getViewRootImpl();if (impl != null) {impl.notifyChildRebuilt();}}//2. 将这个decorview加到windowmanager中去if (a.mVisibleFromClient) {if (!a.mWindowAdded) {a.mWindowAdded = true;wm.addView(decor, l);} else {a.onWindowAttributesChanged(l);}}} else if (!willBeVisible) {//如果本就不要被展示,就设置为hider.hideForNow = true;}// Get rid of anything left hanging around.cleanUpPendingRemoveWindows(r, false /* force */);//现在window可见了,一切正常,做一些可见情况下的设置if (!r.activity.mFinished && willBeVisible&& r.activity.mDecor != null && !r.hideForNow) {if (r.newConfig != null) {performConfigurationChangedForActivity(r, r.newConfig);r.newConfig = null;}WindowManager.LayoutParams l = r.window.getAttributes();if ((l.softInputMode& WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)!= forwardBit) {l.softInputMode = (l.softInputMode& (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION))| forwardBit;if (r.activity.mVisibleFromClient) {ViewManager wm = a.getWindowManager();View decor = r.window.getDecorView();//windowmanager.updateViewLayout//会调用到WindowManagerGlobal.updateViewLayout()//追进去发现这里仅是更新layoutwm.updateViewLayout(decor, l);}}r.activity.mVisibleFromServer = true;mNumVisibleActivities++;if (r.activity.mVisibleFromClient) {r.activity.makeVisible();}}if (!r.onlyLocalRequest) {r.nextIdle = mNewActivities;mNewActivities = r;//这篇文章大概讲了一下idlehandler的用处://主要用于性能优化,在messagequeue空的时候,执行一些动作。https://www.jianshu.com/p/4c2aa7b7d9b3Looper.myQueue().addIdleHandler(new Idler());}r.onlyLocalRequest = false;// Tell the activity manager we have resumed.if (reallyResume) {try {//通知ams我resume了ActivityManager.getService().activityResumed(token);} catch (RemoteException ex) {throw ex.rethrowFromSystemServer();}}} else {// 如果onresume出了错,告诉ams去finish掉这个activity,进行处理activity栈的该有的工作try {ActivityManager.getService().finishActivity(token, Activity.RESULT_CANCELED, null,Activity.DONT_FINISH_TASK_WITH_ACTIVITY);} catch (RemoteException ex) {throw ex.rethrowFromSystemServer();}}
}
到此。我们跟踪完了。总结流程:
- Zygote孵化出一个app进程,通过ActivityThread.main()进入该进程
- ActivityThread中的applicationThread是一个binder实体,通知给ams
- ams收到后,完成注册。
- ams然后让ActivityStackSupervisor去进行activity栈管理,realStartActivityLocked()去发起activity的启动。
- ActivityStackSupervisor通过applicationThread这个binder代理,远程通知app进程,你可以开启activity了。通过:applicationThread.scheduleLaunchActivity()
- app进程收到消息后,将会接连调用activity的onCreate、onStart、onResume,且设置window相关内容
- 首先实例化一个 activity,为其设置一些信息,例如intent消息等
- activity间的数据传递,除了intent,也可以使用一个全局对象传递,我说这个的意思是,app进程在被zygote幅画出来的时候,也持有了一个VM虚拟机,在其中,各个线程有自己的私有数据区,也有进程的共有数据区。在堆中。同一个进程下,可以直接访问到,而不需要再通过binder来ipc传递。(这部分只是突然想到,还没有确认到底是否合适)
- 然后接连发起生命周期回调,如果中间失败了,将会通知ams,我失败了,你要finishActivity()
- 如果resume也完成了,也会通知ams,我ok了
此外,这次源码阅读发现,AMS的引用并没有持久保存在app进程中!每次都通过ServiceManager去寻找AMS的远程代理!!!
每次读源码都会有收获,下一篇分享activity栈的管理,这关联到activity后续的生命周期。