根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
所需的应用进程已经启动的情况。
后面会讲解其余的三个部分。
相关类介绍
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
:ActivityThread
mMainThread.getApplicationThread()
:ApplicationThread
ApplicationThread
是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<IActivityManager> IActivityManagerSingleton =
new Singleton<IActivityManager>() {
@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<ResultInfo> pendingResults,
List<ReferrerIntent> 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》的笔记一起看,那里关于一些细节记录得更详细一些~~
参考
《安卓进阶解密》