根Activity的启动过程
《安卓进阶解密》读书笔记
这里分析的源码基于android-8.0.0_r4.
「根Activity的启动过程」和「Activity的启动_5.0」笔记记录的,有大部分过程是一样的.
概述
根Activity启动过程中设计到的进程及其交互
时序图如下
这里将根Activity的启动划分为四部分
- Launcher请求AMS过程
- AMS判断根
Activity所需的应用程序进程是否已经存在并启动,若不存在,则请求Zygote进程创建应用程序进程,详情查看《应用程序进程启动过程》的笔记。应用程序进程启动后,则进入下一个步骤 - AMS到ApplicationThread的调用过程
- ActivityThread启动Activity的过程
这里先看下第2部分,为什么会存在根Activity所需的应用进程已经启动的情况呢?比如现在要写一个音乐播放器App,第一次打开这个App,那么应用进程当然是未启动的,这时候为了启动根Activity,就需要先启动应用程序进程,再启动根Activity,现在它们都启动完毕,并且运行了一段时间,现在在程序中播放一首歌曲,音乐播放器放在Service中管理,现在按返回键,销毁所有的Activity,销毁完之后,会发现音乐还在播放,这时候虽然Activity都被销毁了,但是进程还是存活的,并且Service还是存活的,音乐仍然在播放,那么这时候,如果点击应用程序的快捷图标,将会启动根Activity,这种情况下就是根Activity所需的应用进程已经启动的情况。
另外,好像没有找到在哪里判断的「根
Activity所需的应用程序进程是否已经存在并启动」的代码,是在ActivityStackSupervisor::startSpecificActivityLocked当中吗?
后面会讲解其余的三个部分。
相关类介绍
Instrumentation:仪表盘,具体到应用程序中是管理Activity的一个工具类,包括创建和启动Activity,Activity的生命周期方法都是由Instrumentation来控制的,一个进程只用一个Instrumentation实例
ActivityManagerService:Android中最核心的服务,主要负责系统中四大组件的启动、切换、调度及应用程序的管理和调度等工作
ActivityThread:管理应用程序进程中主线程的执行,根据Activity管理者的请求调度和执行activities、broadcasts及其相关的操作
ApplicationThread:用来实现ActivityManagerService和ActivityThread之间的交互,是ActivityThread的内部类
ActivityStack:负责单个Activity栈的状态和管理
ActivityStackSupervisor:负责所有Activity栈的管理
ActivityStarter:Android 7.0新加入的类,它是加载Activity的控制类
H:ActivityThread的内部类,继承至Handler,是应用程序进程中主线程的消息管理类
ProcessRecord:用于描述一个应用程序进程
ActivityRecord:用于描述一个Activity,用来记录一个Activity的所有信息
TaskRecord:用于描述一个任务栈
LoadedApk:用来描述已加载的APK文件
Activity:变量说明
mMainThread:ActivityThreadmMainThread.getApplicationThread():ApplicationThreadApplicationThread是ActivityThread的一个内部类,这两个类在Activity启动的过程中都发挥着重要的作用
IBinder
这里简单说明根Activity启动时涉及到的Binder类、Binder接口,这部分内容在《Activity的启动_5.0》笔记中有记录过,但是Android 8.0之前,IActivityManager以及IApplicationThread的定义声明等并没有采用AIDL的形式,而是一种类似AIDL的形式,在Android 8.0中,采取的是一种AIDL的形式
Android 5.0的笔记
IActivityManager:
//Binder接口
public interface IActivityManager extends IInterface {...}
//Binder类,相当于Stub
public abstract class ActivityManagerNative extends Binder implements IActivityManager{.}
//Binder类的具体实现
public final class ActivityManagerService extends ActivityManagerNative implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {...}
//Binder类的本地代理,相当于Proxy,定义在ActivityManagerNative里面,不同进程下,通过 //ActivityManagerNative的asInterface,即可将AMS「继承至Stub」转化为ActivityManagerProxy //「Proxy」
class ActivityManagerProxy implements IActivityManager{...}
IApplicationThread:
//Binder接口
public interface IApplicationThread extends IInterface {...}
//Binder类,相当于Stub
public abstract class ApplicationThreadNative extends Binder implements IApplicationThread {}
//继承至Binder类,也就说这个相当于是Binder类的真正实现,相当于上面AMS的aidl逻辑分析中的Binder_1
private class ApplicationThread extends ApplicationThreadNative {...}
//代理对象如下,定义在ActivityThreadNative里面
class ApplicationThreadProxy implements IApplicationThread {...}
Android 8.0的变化
源码地址:IActivityManager.java.
public interface IActivityManager extends android.os.IInterface{
...
public static abstract class Stub extends android.os.Binder implements
android.app.IActivityManager{
...
private static class Proxy implements android.app.IActivityManager{
...
}
}
}
源码地址:ActivityManagerService.java.
public class ActivityManagerService extends IActivityManager.Stub...{
...
}
形式上和《Android 开发艺术探索》介绍的一样。Android 8.0去除了ActivityManagerNative的内部类ActivityManagerProxy,代替它的是IActivityManager.Stub.Proxy;ActivityManagerService继承至IActivityManager.Stub
IApplicationThread应该也是这样。另外,ApplicationThread是ActivityThread的内部类
这里没有去找源码,所以只能说应该,没找源码是因为aidl文件,是在编译的时候才转化为.java文件,源码怎么找嘛~~
PS:IActivityManager.java是通过代码的跳转链接找到的~~
Launcher请求AMS过程
当我们点击某个应用程序的快捷图标时,就会通过Launcher请求AMS来启动该应用程序,也就是启动根Activity,时序图如下
首先查看Launcher的继承关系
public class Launcher extends BaseActivity implements ... {...}
public abstract class BaseActivity extends Activity {...}
可以看出,Launcher就是Activity的子类.
首先是Launcher的startActivitySafely方法
public boolean startActivitySafely(View v, Intent intent, ItemInfo item) {
...
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//该Flag表明根Activity会在新的任务栈启动
...
startActivity(intent, optsBundle);
...
}
调用父类Activity的startActivity方法
public void startActivity(Intent intent, @Nullable Bundle options) {
...
if (options != null) {
startActivityForResult(intent, -1, options);
} else {
startActivityForResult(intent, -1);
}
}
这里出现了startActivityForResult方法的两个重载,两个参数的那个方法,最终会调用到三个参数的,如下
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode) {
startActivityForResult(intent, requestCode, null);
}
这里查看三个参数的startActivityForResult方法
# requestCode:如果requestCode >= 0,该Activity销毁时,requestCode值会返回到
# onActivityResult方法里
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);
...
} else {
...
}
}
-
Activity mParent代表的是ActivityGroup,ActivityGroup最开始被用来一个界面中嵌入多个子Activity,后来在API 13中被废弃了,使用Fragment代替,所以这里只用看mParent == null的逻辑 -
这里传入的
requestCode的值为-1,表明Launcher不需要知道Activity启动的结果
接着查看Instrumentation的execStartActivity方法
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
...
try {
...
int result = ActivityManager.getService()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}
这里通过ActivityManager.getService()获取到AMS的本地代理,远程调用AMS的startActivity,首先查看ActivityManager.getService()方法
public static IActivityManager getService() {
return IActivityManagerSingleton.get();
}
private static final Singleton IActivityManagerSingleton =
new Singleton() {
@Override
protected IActivityManager create() {
final IBinder b =
ServiceManager.getService(Context.ACTIVITY_SERVICE);
final IActivityManager am = IActivityManager.Stub.asInterface(b);
return am;
}
};
这里通过单例类Singleton获取AMS的本地代理,Android 8.0之前 是通过ActivityManagerNative的getDefault来完成的,Android 8.0则将该逻辑封装到了ActivityManager当中
进程切换:Launcher进程 -> AMS所在进程(SystemServer进程)
AMS -> ApplicationThread
接下来的逻辑就进入了AMS所在进程.
时序图如下
下面只列举出几个重要的方法
首先是ActivityStarter的几个方法,先说一下ActivityStarter这个类,Android 7.0新加入的,是加载Activity的控制类,它会收集所有的逻辑,来决定如何将Intent和Flags转换为Activity,并将Activity和Task以及Stack相关联.
ActivityStarter::startActivity,这里讲解的是第一个startActivity方法
private int startActivity(IApplicationThread caller ...) {
...
ProcessRecord callerApp = null;
if (caller != null) {
callerApp = mService.getRecordForAppLocked(caller);
...
}
...
//创建即将要启动的Activity的描述类ActivityRecord
ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
mSupervisor, container, options, sourceRecord);
//outActivity:ActivityRecord[]类型
if (outActivity != null) {
outActivity[0] = r;
}
}
-
caller:方法调用一路传来,是
Launcher进程的Instrumentation::execStartActivity传来的,指向的是Launcher进程的ApplicationThread对象 -
callerApp:代表
Launcher进程的ProcessRecord对象
ActivityStarter::startActivityUnchecked,该方法主要处理与栈管理相关的逻辑
private int startActivityUnchecked(...){
...
//1.
if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
&& (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
newTask = true;
//2.
result = setTaskFromReuseOrCreateNewTask(
taskToAffiliate, preferredLaunchStackId, topStack);
}
...
//3.
mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
mOptions);
}
-
注释1:在
Luncher::startActivitySafely中,会为根Activity的Intent设置FLAG_ACTIVITY_NEW_TASK的Flag,在注释1中可以进入If语句 -
注释2:内部会创建一个新的Activity任务栈,创建一个新的
TaskRecord -
注释3:调用
ActivityStackSupervisor::resumeFocusedStackTopActivityLocked
ActivityStackSupervisor::startSpecificActivityLocked
void startSpecificActivityLocked(ActivityRecord r,
boolean andResume, boolean checkConfig) {
//1.获取即将启动的Activity的所在的应用程序进程
ProcessRecord app = mService.getProcessRecordLocked(r.processName,
r.info.applicationInfo.uid, true);
r.getStack().setLaunchTime(r);
//2.
if (app != null && app.thread != null) {
try {
...
//3.
realStartActivityLocked(r, app, andResume, checkConfig);
return;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting activity "
+ r.intent.getComponent().flattenToShortString(), e);
}
// If a dead object exception was thrown -- fall through to
// restart the application.
}
// 如果进程不存在,则通过zygote创建应用进程
mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
"activity", r.intent.getComponent(), false, false, true);
}
- 注释2:
app指的是即将启动的Activity的所在的应用程序进程;app.thread的类型是IApplicationThread,它的实现是要启动的Activity所在的应用程序进程的ActivityThread的内部类ApplicationThread,ApplicationThread继承了IApplication.Stub,这里app.thread得到的是ApplicationThread在SystemServer进程的代理 - 注释3:调用自身的
realStartActivityLocked方法
ActivityStackSupervisor::realStartActivityLocked
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
boolean andResume, boolean checkConfig) throws RemoteException {
...
app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
System.identityHashCode(r), r.info,
mergedConfiguration.getGlobalConfiguration(),
mergedConfiguration.getOverrideConfiguration(), r.compat,
r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
r.persistentState, results, newIntents, !andResume,
mService.isNextTransitionForward(), profilerInfo);
...
return true;
}
这里调用了app.thread的scheduleLaunchActivity,也就是调用应用程序进程的ApplicationThread的scheduleLaunchActivity方法
进程切换:AMS所在进程(SystemServer进程) -> 即将启动的Activity所在的应用程序进程
ActivityThread启动Activity的过程
目前代码逻辑运行在应用程序进程,时序图如下
ApplicationThread::scheduleLaunchActivity
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 pendingResults,
List pendingNewIntents,boolean notResumed,
boolean isForward, ProfilerInfo profilerInfo) {
updateProcessState(procState, false);
//将启动Activity的参数封装成ActivityClientRecord
ActivityClientRecord r = new ActivityClientRecord();
r.token = token;
r.ident = ident;
r.intent = intent;
r.referrer = referrer;
...
updatePendingConfiguration(curConfig);
sendMessage(H.LAUNCH_ACTIVITY, r);
}
向H类发送类型为H.LAUNCH_ACTIVITY的消息,并将ActivityClientRecord传递过去,H类是ActivityThread的内部类,继承至Handler,是应用程序进程中主线程的消息管理类
ActivityThread::sendMessage
private void sendMessage(int what, Object obj) {
sendMessage(what, obj, 0, 0, false);
}
private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
if (DEBUG_MESSAGES) Slog.v(
TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
+ ": " + arg1 + " / " + obj);
Message msg = Message.obtain();
msg.what = what;
msg.obj = obj;
msg.arg1 = arg1;
msg.arg2 = arg2;
if (async) {
msg.setAsynchronous(true);
}
mH.sendMessage(msg);
}
由于ApplicationThread是一个Binder,它的调用逻辑运行在Binder线程池中,因此这里通过H,将代码逻辑切回主线程.
线程切换:应用程序Binder线程 -> 应用程序主线程
H::handleMessage
private class H extends Handler {
...
public void handleMessage(Message msg) {
if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
switch (msg.what) {
case LAUNCH_ACTIVITY: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
//1.
r.packageInfo = getPackageInfoNoCheck(
r.activityInfo.applicationInfo, r.compatInfo);
//2.
handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
} break;
...
}
...
}
}
- 注释1:获取LoadedApk类型的对象赋值给
ActivityClientRecord的packageInfo,应用程序进程要启动Activity时需要将该Activity所属的APK加载进来,而LoadApk就是用来描述已加载的APK文件的 - 调用
ActivityThread::handleLaunchActivity
ActivityThread::handleLaunchActivity
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
...
//启动Activity
Activity a = performLaunchActivity(r, customIntent);
if (a != null) {
r.createdConfig = new Configuration(mConfiguration);
reportSizeConfigurations(r);
Bundle oldState = r.state;
//将Activity的状态设置为Resume
handleResumeActivity(r.token, false, r.isForward, !r.activity.mFinished
&& !r.startsNotResumed, r.lastProcessedSeq, reason);
if (!r.activity.mFinished && r.startsNotResumed) {
performPauseActivityIfNeeded(r, reason);
if (r.isPreHoneycomb()) {
r.state = oldState;
}
}
} else {
try {
//如果Activity为null,则通知AMS停止启动Activity
ActivityManager.getService()
.finishActivity(r.token, Activity.RESULT_CANCELED, null,
Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
}
ActivityThread::performLaunchActivity
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
//1.获取ActivityInfo类
ActivityInfo aInfo = r.activityInfo;
if (r.packageInfo == null) {
//2.获取APK文件的描述类LoadedApk
r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
Context.CONTEXT_INCLUDE_CODE);
}
//3.获取要启动的Activity的ComponentName
//ComponentName保存了该Activity的包名和类名
ComponentName component = r.intent.getComponent();
...
//4.创建要启动的Activity的上下文环境
ContextImpl appContext = createBaseContextForActivity(r);
Activity activity = null;
try {
java.lang.ClassLoader cl = appContext.getClassLoader();
//5.用加载器来创建该Activity的实例
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
...
} catch (Exception e) {
...
}
try {
//6.尝试创建Application,makeApplication内部会调用Application的onCreate
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
...
if (activity != null) {
...
appContext.setOuterContext(activity);
//7.初始化Activity
//内部包括创建PhoneWindow与Activity自身关联;关联ContextImpl...
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);
...
if (r.isPersistable()) {
//8.调用Instrumentation::callActivityOnCreate启动Activity
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
...
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) {
...
}
return activity;
}
注释4:创建Activity的上下文环境
private ContextImpl createBaseContextForActivity(ActivityClientRecord r) {
...
ContextImpl appContext = ContextImpl.createActivityContext(
this, r.packageInfo, r.activityInfo, r.token, displayId, r.overrideConfig);
...
return appContext;
}
在Activity的attach中会将ContextImpl进行关联
注释6:尝试创建Application,r.packageInfo的类型是LoadedApk,LoadedApk::makeApplication
public Application makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation) {
// 如果Application已经被创建过了,那么就不会再重复创建了,这意味着一个应用进程只有
// 一个Application对象
if (mApplication != null) {
return mApplication;
}
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "makeApplication");
Application app = null;
...
try {
java.lang.ClassLoader cl = getClassLoader();
...
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
// Application对象的创建通过Instrumentation来完成,内部通过类加载器来实现
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
appContext.setOuterContext(app);
} catch (Exception e) {
...
}
mActivityThread.mAllApplications.add(app);
mApplication = app;
if (instrumentation != null) {
try {
// 这里面会调用Application的onCreate()方法
instrumentation.callApplicationOnCreate(app);
} catch (Exception e) {
...
}
}
...
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
return app;
}
回到ActivityThread的performLaunchActivity中,调用了Instrumentation::callActivityOnCreate
public void callActivityOnCreate(Activity activity, Bundle icicle,
PersistableBundle persistentState) {
prePerformCreate(activity);
activity.performCreate(icicle, persistentState);
postPerformCreate(activity);
}
Activity::performCreate
final void performCreate(Bundle icicle, PersistableBundle persistentState) {
restoreHasCurrentPermissionRequest(icicle);
onCreate(icicle, persistentState);
mActivityTransitionState.readState(icicle);
performCreateCommon();
}
Activity::onCreate
public void onCreate(@Nullable Bundle savedInstanceState,
@Nullable PersistableBundle persistentState) {
onCreate(savedInstanceState);
}
调用到了void onCreate(@Nullable Bundle savedInstanceState) {...},至此,根Activity就启动了,即应用程序就启动了
可以结合《Activity的启动_5.0》的笔记一起看,那里关于一些细节记录得更详细一些~~
参考
《安卓进阶解密》