本文章仅供自己复习用,参考了这位大神的文章
Android应用启动流程分析
下面正式开始文章
前言
一个android home界面可以看作是一个大的app,我们把他称作launcher,当我们点击一个app开始启动时,即调用startactivity方法。在了解启动流程之前,我们必须要知道的工具类有
- Instrumention:负责管理ams
- Activitythread: 应用的入口类,通过main函数开启looper的循环。activitythread所在的线程称为主线程(ui线程)
- ams:android最核心的服务,负责四大组件的启动切换调度以及应用进程的管理和调度等工作,他本身是一个binder类的实现,应用进程通过binder机制调用系统服务
- activitystarter:activity的启动工具,处理activity的各种flag
- activitystackSupervisior:管理所有应用的activity栈,其中mFocusedStack就是当前应用的activity栈
binder机制
binder机制运用到的是c/s模式,client即我们的app进程,server就是zygote相关进程。zygote进程就相当于一个服务端,当客户端需要请求时,会首先把zygote进程fork出一个新zygote进程,然后开启我们的目标app
- 本地代理与远程代理:一般从命名上可以分辨,xxNative是本地代理,xxProxy是在对方进程的binder代理
- serviceManager的统一管理:ServiceManager管理所有的Android系统服务,有人把ServiceManager比喻成Binder机制中的DNS服务器,client端应用如果要使用系统服务,调用getSystemService接口,ServiceManager就会通过字符串形式的Binder名称找到并返回对应的服务的Binder对象。
服务端:Iactivitymanger--activitymanagerNative--AMS。
具体分析:AMN(ActivityManagerNative)作为服务器的stub(庄),其职责是对远程传递过来的数据进行反序列化
AMP(ActivityManagerProxy)作为服务启动代理,运行在客户端,负责将数据序列化传递给stub。在app中使用ams提供的功能,比如startActivity,是通过ams在客户端的代理AMP发起的
最下面一层是stub的具体实现---AMS
客户端:IApplicationThread--ApplicationThreadNative--ActivityThread
桩(stub):ApplicationNative
代理(Proxy):ApplicationThreadProxy,AMS通过客户端的ApplicationThreadProxy来处理实现实例化activity,调用oncreate等生命周期的函数的功能
最下面一层是桩(stub)的实现--applicationthread,他是activitythread的一个内部类,application负责响应系统进程发起的请求,而activitythread负责实际触发的业务逻辑。处理的请求要发送到activitythread的一个handler类上
通信过程分析
其具体的过程就是一个c/s模式的通信模型
private void attach(boolean system, long startSeq) {
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) {
android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
UserHandle.myUserId());
RuntimeInit.setApplicationObject(mAppThread.asBinder());
final IActivityManager mgr = ActivityManager.getService();
try {
mgr.attachApplication(mAppThread, startSeq);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
首先客户端中存在ams的代理类,通过该代理进行binder层次的信息传递,这就完成了从应用进程到系统进程,之后再从系统进程返回应用进程。而应用进程返回消息给系统进程,通过server端的proxy,调用bindapplicaiton方法调用返回的数据
private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
int pid, int callingUid, long startSeq) {
thread.bindApplication(processName, appInfo, providerList, null, profilerInfo,
null, null, null, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.isPersistent(),
new Configuration(app.getWindowProcessController().getConfiguration()),
app.compat, getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked(),
buildSerial, autofillOptions, contentCaptureOptions,
app.mDisabledCompatChanges);
application的创建需要一些参数,由processrecord维护
- AMS通过ProcessRecord来维护进程运行时的状态信息,需要将应用进程绑定到ProcessRecord才能开始一个Application的构建;
- AMS维护的ProcessRecord这个数据结构,包含了进程运行时的信息,譬如应用进程的名称processName、解析AndroidManifest.xml得到的数据结构ApplicationInfo等,其中,要传递给应用进程的数据都是Parcelable类型的实例。
最后,在系统进程发送了binder通信之后,应用进程实现application的创建
ApplicationThread.onTransact()
└── ApplicationThread.bindApplication()
└── ActivityThread.H.handleMessage(BIND_APPLICATION)
└── ActivityThread.handleBindApplication()
└── Application.onCreate()
这样就完成了application的创建。现在我们再回顾以下application创建经历了哪些类
应用进程to系统进程
ActivityThread.main()
└── ActivityThread.attach()
└── IActivityManager.attachApplication(mAppThread)
└── Binder.transact()
ActivityManagerService.onTransact()
└── ActivityManagerService.attachApplication(IApplicationThread thread)
系统进程to应用进程
ActivityManagerService.attachApplication()
└── ActivityManagerService.attachApplicationLocked()
└── IApplicationThread.bindApplication(processName, appInfo ...)
└── Binder.transact()
ApplicationThread.onTransact()
└── ApplicationThread.bindApplication()
└── ActivityThread.H.handleMessage(BIND_APPLICATION)
└── ActivityThread.handleBindApplication()
└── Application.onCreate()
创建完application,即可以准备实现activity的创建,我们可以在后面再说,先继续谈一下activity中应用进程与系统进程的通信模型
在启动一个新的Activity时,AMS会将ActivityRecord的Token传递给应用进程,调用关系如下所示:
ActivityStackSupervisor.realStartActivityLocked(ActivityRecord, ...)
└── IApplicationThread.scheduleLaunchActivity(...token, ...)
// 将ActivityRecord的Token跨进程传递给应用进程
└── Binder.transact()
ActivityStackSupervisor.realStartActivityLocked()表示要启动一个Activity实例,ActivityRecord作为参数。从ActivityRecord中提取出Token对象,作为跨进程调用的参数,通过IApplicationThread.scheduleLaunchActivity()传递到应用进程。
在应用进程这一侧,会收到启动Activity的跨进程调用,触发以下函数的调用:
ApplicationThread.onTransact()
└── ApplicationThread.scheduleLaunchActivity(...token, ...)
// token将被封装进ActivityClientRecord这个数据结构中
└── ActivityThread.H.handleMessage()
└── ActivityThread.handleLaunchActivity(LAUNCH_ACTIVITY)
└── ActivityThread.performLaunchActivity(ActivityClientRecord, ...)
// 从ActivityRecord取出token
└── Activity.attch(...token, ...)
标准的Binder服务端处理流程,收到AMS传递过来的Token对象,进行一下数据封装(ActivityClientRecord),然后通过Handler抛出一个LAUNCH_ACTIVITY消息。这个消息显然也是抛到了应用进程的主线程去执行,所以ActivityThread.performLaunchActivity()函数会在主线程上执行,该函数从封装的数据结构ActivityClientRecord中取出Token对象,调用Activity.attach()函数,将其绑定到Activity上,如此一来,就建立应用进程的Activity与系统进程中ActivityRecord的关联。
系统进程维护的是ActivityRecord,应用进程维护的是Activity,两者之间的映射关系就是利用Token来维系的。
activity的启动流程
- 当点击桌面app时,发起进程就是launcher所在进程,启动远程进程system_server
- 在system_server进程中,会先调用process.start()方法,通过socket通信去通知zygote进程fork子进程,进程创建后将activitythread加载进去,执行activity的main方法
- 在activitythread的main方法里,存在binder通信方的内部类applicationthread的实现,looper的循环,handler对象。而主要负责推进的是activitymanagerproxy通过binder通信对server端发送序列化之后的数据
- 在system_server端,通过ams的attachapplication()向client端即Activitythread发送application创建数据,通过activitythread.handlebindapplication()创建application对象,并且attach(context)来绑定context,完成了activity创建前的准备
- 在上一步执行的同时,在ams中会调用ActivitystackSupervisor类中的方法,这个类是activity的栈管理器,通过回调mStackSupervisor#attachApplicationLocked(),进而调用了ActivityThread#ApplicationThread#scheduleLaunchActivity() 方法,最终通过handler通信方式 ActivityThread#sendMessage(H.LAUNCH_ACTIVITY, r) 方法,最终走到了 ActivityThread#handleLaunchActivity() ,进而创建 Activity 对象
然后调用 activity.attach() 方法,再调用 mInstrumentation#callActivityOnCreate() 执行 Activity#onCreate() 生命周期;
部分源码解析
在ams中调用了activitystater类中的方法
@Override
public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
enforceNotIsolatedCaller("startActivity");
userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
userId, false, ALLOW_FULL_ONLY, "startActivity", null);
// TODO: Switch to user app stacks here.
return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
profilerInfo, null, null, bOptions, false, userId, null, null,
"startActivityAsUser");
}
activitystarter又再向下调用了activitystacksupvisor类中的方法
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
ActivityRecord[] outActivity) {
···
if (mDoResume) {
final ActivityRecord topTaskActivity =
mStartActivity.getTask().topRunningActivityLocked();
if (!mTargetStack.isFocusable()
|| (topTaskActivity != null && topTaskActivity.mTaskOverlay
&& mStartActivity != topTaskActivity)) {
···
} else {
···
mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
mOptions);
}
} else {
···
}
···
}
然后这两个类的方法最终回调到ams
void startSpecificActivityLocked(ActivityRecord r,
boolean andResume, boolean checkConfig) {
···
if (app != null && app.thread != null) {
try {
···
// 如果进程已存在,则通知进程启动组件
realStartActivityLocked(r, app, andResume, checkConfig);
return;
} catch (RemoteException e) {
···
}
}
// 否则先将进程创建出来
mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
"activity", r.intent.getComponent(), false, false, true);
}
在activitystackSupervisor类有一个方法 mStackSupervisor#attachApplicationLocked()调用了 ActivityThread#ApplicationThread#scheduleLaunchActivity()
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,
// 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) {
···
}
···
}
//ActivityStackSupervisor.java
@Override
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) {
···
sendMessage(H.LAUNCH_ACTIVITY, r);
}
//ActivityThread#ApplicationThread.java
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) {
···
mH.sendMessage(msg);
}
//ActivityThread.java
最后执行activity的oncreate()方法
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
···
Activity a = performLaunchActivity(r, customIntent);
···
}
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
···
Activity activity = null;
try {
//创建 Activity 对象
java.lang.ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
···
} catch (Exception e) {
···
}
try {
···
if (activity != null) {
···
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);
···
//执行 Activity#onCreate() 生命周期
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
···
}
···
} catch (SuperNotCalledException e) {
···
} catch (Exception e) {
···
}