Activity启动分为两种情况
- Activity所在进程不存在,冷启动
- Activity所在进程存在于后台
针对于这两种情况,我们都可以对此用一套流程来描述,针对冷启动情况,其中会添加一部分创建ActivityThread的流程
还是先上图,图片出处GitYuan
假设在图片流程之前,我们做的是点击桌面按钮操作,那么会去执行activity的startActivity操作,该方法里面会通过Instrumetation这个大管家去调用其他方法
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
if (mParent == null) {
options = transferSpringboardActivityOptions(options);
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
if (ar != null) {
mMainThread.sendActivityResult(
mToken, mEmbeddedID, requestCode, ar.getResultCode(),
ar.getResultData());
}
...
}
在这个方法里面才是真正地通过AMS操作activity,注意,此时的Context,ContextThread,Token都是发起方Activity的,不是被调起方的。其中的ContextThread为发起方所在的ActivityThread中的ApplicationThread属性,该属性为Binder类型,用来和AMS进行交互
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
int result = ActivityManager.getService()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
}
下面会通过ActivityStack类中的封装,执行startActivityMayWait()
int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
null, null, bOptions, ignoreTargetSecurity, userId, null, null);
在ActivityStarter.java的startActivityMaywait()方法中,再调用startActivityLocked()方法,进一步调用startActivityUnchecked()。用图表示如下
- Instrumentation.execStartActivity()
- AMS.startActivity()
- ActivityStarter.startActivityMayWait()
- ActitivityStarter.startActivityLocked()
- ActitivityStarter.startActivityUnchecked()(此处设计到启动模式,另外还会打印EventLog:Activity Oncreate)
- ActitivityStarter.startActivityLocked()
- ActivityStarter.startActivityMayWait()
- AMS.startActivity()
接着上图,AMS后面会将Activity的处理放到ActivityStackSupervisor类中。其中值得注意的几个地方如下:
- startActivityUncheckedLocked方法中会涉及到LaunchMode启动模式相关
- resumeTopActivityLocked方法中会去将当前的可见Activity设置为Pause状态
- startSpecialActivity()方法中会去判断要启动的Activity对应的进程是否存在,如果存在,
- 调用realStartActivityLocked()
此处会判断是不是当前activity已经处于pause状态,如果还没有完成pause工作,将会打印Skipping start of r some activitys pausing的log - 打印AM_RESTART_ACTIVITY
- ApplicationThread执行scheduleLaunchActivity,此处还在ActivityStackSupervisor中执行,也就是说运行到此时是在system_server进程中,通过IPC调用call到了应用进程,我需要通过IAppicationThread通过Handler的方式去通知ActivtiyThread,ApplicationThread作为ActivityThread的内部类,可以和ActivityThread进行通信
- ActivityThread执行handleLaunchActivity
- handleLaunchActivity中执行performLaunchActivity()方法,该方法中会new activity new window activity.attach(window) onCreate() onStart()。其中new activity是通过反射的方式来获取到的;window的创建和绑定都在Activity.attach()中完成的;onCreate()和onStart()方法都是通过mInstrumentation来回调的;同时attach()中还完成了attachBaseContext操作。
- handleResumeLunchActivity(),该方法中先执行performResumeAtivity(),进一步调用时,可能会执行performRestart(),一定会走performResume()最终调用onResume();然后是对window的处理,将前面已经添加成功的根view,也就是decorView添加到wm中。wm.addView(decor,l);
- onResume
- 调用realStartActivityLocked()
如果不存在该进程
1. AMS.startProcessLocked()
2. zygote fork new process;Process.start()
3. ActivityThread.main()
4. Looper.prepareMain()/ActivityThread.atttach(false),Loop.loop()
5. AMS.attachApplication(IAppicationThread)建立起ActivityThread和AMS之间的联系,在AMS.attachApplication()方法中,会调用thread.bindApplication(进程相关属性),调用完后通过Handler传递给ActivityThread执行handleBindApplication操作。AMS.attachApplication()中还有一件重要的事情就是最终调用realStartActivity()。具体过程为:
//AMS中的attachApplication()方法
void attachApplication(){
...
thread.bindApplication(...);
...
mStackSupervisor.attachApplicationLocked();//最终调用realStartActivity()
}
-----2020新增----
新的Activity生命周期处理流程
后来, Android引入了 JetPacket框架后,新增了 Life Cycle念,可以让应用通过 addobserver的方式方便地监听到 activity /fragment的生命
周期。同时在启动 acitivity的地方做出了一些修改,目的是为了让activity的生命周期操作从原来的 ActivityThread中到剥离出来,使用新的类来管理生命周期,如 LaunchActivityltem/ResumeActivityltem/ PauseAcitivtyltem等。这些类都在 android/app/transilatonserve径下。原来的 acitivty启动流程走到 ActivityStackSuperVisor走到 realStartActivity后,里面调用了ATMS.gstlifecyclemanager.scheduleTransaction(clinet) 方法,其中,client有上述item信息。这样便开始了生命周期行为。 LaunchActivityltem中持有 Application Thread,可以方便地和app测进行交互
从ActivityThread.mH中的代码来看,之前的activity生命周期相关的launch message处理交给了EXECUTE_TRANSACTION处理。
这些XActivityItem都继承自ActivityLifecycleItem extends ClientTransactionItem
上面说的用来管理这些单独ActivityLifeCycleItem的类如下: