Activity的启动分析
一、什么是Activity的启动和名词解释
什么是:
在后面的解析过程中会遇到很多生类(单词)这里把它们列出来(其中大多数描述也是来自其他博客):
ActivityMangerServices
简称AMS,服务端对象,负责系统中所有Activity的生命周期。AMS是作为管理Android系统组件的核心服务,他在SystemServer执行run()方法的时候被创建,并运行在独立的进程中。具体来说就是SystemServer管理着Android中所有的系统服务,这些系统服务的生命周期回调都由System Server去调度负责。
ActivityThread
App的真正入口。当开启App之后,会调用main()方法,开启消息循环列表,运行在主线程上。与ActivityManagerSevices配合,一起完成Activity的管理工作。
ApplicationThread
是ActivityThread的一个内部类 ,用来实现ActivityManagerService和ActivityThread之间的交互。在AMS需要管理相关Application中的Activity的生命周期时,通过ApplicationThread的代理对象与ActivityThread通讯。
ApplicationThreadProxy
是ApplicationThread在服务器端的代理,负责和客户端的ApplicationThread通讯。(通信:应用层,通讯:物理层)
二、大概启动流程
下面是我按照《Android 开发艺术探索》一书整理出来的启动流程(即:客户端发出启动请求,服务端接收请求,并应答启动Activity的过程):
startActivity() ->
startActivityForResult() ->
在上个方法中有(当mParent == null) ->
通过instrumentation对象调用execStartActivity()方法 ->
创建ActivitymanagerNative.getDefault()对象,即AMS对象。并调用它的startActivity()方法(此时才是Activity的真正启动实现) ->
return 调用startActivityAsUser()方法 ->
return 通过mStackSupervisor(ActivityStackSupervisor类)对象的startActivityMayWait()方法(此时Activity的启动转移到了这个方法中) ->
调用startActivityLocked()方法 ->
调用startActivityUncheckerLocked()方法 ->
调用ActivityStack的resumeTopActivitiesLocked()方法(此时已从ActivityStackSupervisor转移到了ActivityStack) ->
调用resumeTopActivityInnerLocked()方法 ->
调用 ActivityStackSupervisor的startSpecificActivityLocked方法 ->
调用了realStartActivityLocked()方法 ->
在上个方法中有这样一句app.thread.scheduleActivity(),其中app.thread的类型为IApplicationThread(它是Binder接口,其实现者是ApplicationThreadNative,由于它是抽象类,所以ApplicationThread就是IApplicationThread最终实现者)。 ->
scheduleLaunchActivity()的实现内容是发送一个启动Activity的消息交由Handler(名字:H)处理。->
Handler H对消息的处理 ->
在ActivityThread的handleLaunchActivity方法中,performLaunchActivity方法实现Activity对象的创建和启动过程,并通过handleResumeActivity方法来启动Activity的onResume这一生命周期。
三、详细过程(具体跟踪)
看了书和很多和博客在讲这一部分的时候都是从startActivity()开始的。
startactivity()方法有很多重载的方法,我找到了它的两个重载方法:
@Override
public void startActivity(Intent intent) {
this.startActivity(intent, null);
}
@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
if (options != null) {
startActivityForResult(intent, -1, options);
} else {
// Note we want to go through this call for compatibility with
// applications that may have overridden the method.
startActivityForResult(intent, -1);
}
}
可以看出最终还是调用了startActivityForResult()方法,这个方法也有很多重载方法,但是我发现它们都做一件事就是用Instrumentation类的对象mIstrumentation调用execStartActivity()方法
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, who,
intent, requestCode, options);
if (ar != null) {
mMainThread.sendActivityResult(
mToken, who, requestCode,
ar.getResultCode(), ar.getResultData());
}
cancelInputsAndStartExitTransition(options);
在execStartActivity()方法中,启动Activity真正的实现是由ActivityMangerNative.getDefault()调用startActivity方法实现的。
//这是execStartActivity()方法中创建AMS并调用startActivity方法
int result = ActivityManagerNative.getDefault()
.startActivity(whoThread, who.getBasePackageName()
,token, target != null ? target.mEmbeddedID : null, requestCode, 0, null, options);
//用来检查Activity的启动结果
checkStartActivityResult(result, intent);
那么ActivityMangerNative.getDefault()肯定是个对象了,是谁?
看ActivityManagerNative.getDefault(),它是一个IActivityManger类型的Binder对象。下面来分析一下:
ActivityManagerNative继承自Binder并实现了IActivityManager这个Binder接口,AMS(ActivityManagerService缩写)继承自ActivityManagerNative,因此AMS也是一个Binder,它是IActivityManager的实现。.getDefault()就是实例化的过程,它是一个AMS对象,AMS采用的是单例模式。.getDefault()的getDefault方法中就一句话return gDefault.get()
(补充:Singleton’<’IActivityManger’>’是一个单例的封装类,gDefault是它的一个对象)下面就是我从ActivityManagerNative源码中截取的(为方便理解,看一看就好,不需要详细了解):
private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
protected IActivityManager create() {
IBinder b = ServiceManager.getService("activity");
if (false) {
Log.v("ActivityManager", "default service binder = " + b);
}
IActivityManager am = asInterface(b);
if (false) {
Log.v("ActivityManager", "default service = " + am);
}
return am;
}
};
由于单例模式,get方法第一次调用时用create方法初始化对象,后面再调用直接返回之前已创建的对象。此时AMS对象就创建出来了,然后就可以继续我们的Activity启动过程,调用它的startActivity()方法。
在startActivity方法中并没有太多内容,它通过return调用startActivityAsUser方法,并传入startActivity方法的所有参数并在最后加入一个UserHandle.getCallingUserId()。代码如下:
public final int startActivity(IApplicationThread caller, String callingPackge, Intent intent
, String resovledType, IBinder resultTo, String resultWho, int requsetCode, int startFlags
, ProfilerInfo profilerInfo, Bundle options){
return startActivityAsUser(caller, callingPackge, intent, resovledType, resultTo
, resultWho, requserCode, startFlags, profilerInfo, options, UserHandle.getCallingUserId());
}
在这个方法中将Activity的启动又转移到ActivityStackSupervisor的startActivityMayWait()方法,startActivityMayWait方法又调用了startActivityLocked()方法,这个方法又调用startActivityLocked()方法,接着又调用了ActivityStack栈resumeTopActivityLocked()方法,这个时候Activity的启动已经从ActivityStackSupervisor转移到了ActivityStack。下面先给出一张图看一下调用关系:
Activity启动过程在ActivityStackSupervisor和ActivityStack之间的传递顺序如上图。
final boolean resumeTopActivityLocked(ActivityRecored prev, Bundle options){
if(inResumeTopActivity){
return false;
}
boolean result = flase;
try{
inResumeTopActivity = true;
result = resumeTopActivityInnnerLocked(prev, options);
}finally{
inResumeTopActivity = false;
}
return result;
}
从上面代码可以看出,resumeTopActivity方法有调用了本栈(ActivityStack栈)中的一个方法resumeTopActivityInnnerLocked方法,resumeTopActivityInnnerLocked方法又调用了ActivityStackSupervisor栈中的startSpecificActivityLocked方法,这个方法用来检查是否需要创建进程,下面是startSpecificActivityLocked方法的代码:
void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig){
//Is this activity's application already running?
ProcessRecord app = mService.getProcessRecord(r.processName, r.info.applicationInfo.uid, true);
r.task.stack.setLaunchTime(r);
if(app!= null && app.thread != null){
try{
if((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
|| !"android".equals(r.info.packageName)){
//Don't add this if it is a platform component that is marked
//to run in multiple processes , because this is marked
//part of the framework so doesn't make sense to track as a sparate apk in the process.
app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode, mService.mProcessStats);
}
realStartActivityLock(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.
}
mService.startProcessLocked(r.processName, r.info.application, true, 0, "activity", r.intent.getComponent(), false , false, true);
}
从上面代码看出,startSpecificActivityLocked方法调用了realStartActivityLocked方法。然后realStartActivityLocked方法中有如下一段代码:
app.thread.scheduleLaunchActivity(new Intent(r.intent)), r.appTaken, System.identityHashCode(r), r.info
, new Configuration(mSevice.mConfiguration), r.compat, r.task.voiceInteractor, app.repProcState, r.icicle
, r.persistentState, results, newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);
其中,app.thread的类型为IApplicationThread,IApplicationThread为Interface类型:
public interface IApplicationThread extends IInterface
它里面包含了大量启动、停止Activity的接口,此外还包含了启动和停止服务的接口。从方法名字可以看出,IApplicationThread这个IBinder接口的实现者完成了大量Activity以及Sevice启动/停止相关的功能。
那么这个实现者到底是谁呢?即IApplicationThread的实现者是谁?
答案是ActivityThread中的内部类ApplicationThread。看如下关系:
private class ApplicationThread extends ApplicationThreadNative
public abstract class ApplicationThreadNative extends Binder implements IApplicationThread
而且在ApplicationThreadNative的内部,还有一个ApplicationThreadProxy类,这个类的是实现如下:
class ActivityManagerProxy implements IActivityManager
{
public ActivityManagerProxy(IBinder remote)
{
mRemote = remote;
}
public IBinder asBinder()
{
return mRemote;
}
\\这个类里面有很多关于Activity的方法
...
}
最终,Activity的启动回到了AppliacationThread中,ApplicationThread通过scheduleLaunchActivity方法来启动Activity。
scheduleLaunchActivity的实现很简单,就是发送一个启动的消息,然后给Handler(它的名字:H)的handleMessage方法然后通过ActivityThread的ActivityThread的handleLaunchActivity处理,在这个方法中调用performLaunchActivity方法,这个方法完成了Activity对象的创建和启动过程,并且ActivityThread通过handleResumeAcitivity方法来调用被启动Activity的onResume这一生命周期。
四、设计思路
从startActivity开始,判断该Activity是否存在,不存在的话,创建(单例)AMS对象,调用startActivity方法,经过在ActivityStackSupervisor栈和ActivityStack栈之间调用函数检查状态及安全,最后由ActivityStackSupervisor栈的realStartActivity方法创建activity对象和启动activity生命周期onResume。AMS的代理对象(ApplicationThreadProxy类对象。现在在ApplicationThread)启用的scheduleLaunleLaunchActivity方法发送一个消息给Handler H(H是名字)对象,到ActivityThread的handleLunchActivity方法,这个方法调用performLaunchActivity方法最终完成Activity的启动和创建过程。
疑问1:怎么管理Activity的启动过程的?谁来管理?
答:ActivityManagerSevice来管理,具体是通过AMS的代理对象ActivityMagerProxy(这个类是AIDL自动生成的)对象来管理。
五、好的设计和新点
1.用了代理模式来管理,使对Activity生命周期的管理事务积聚在了一起并由专门的对象来管理。
2.使用了AIDL。
六、意义(知道Activity启动过程能干什么?)
1)了解Activity的启动过程可以知道应用启动中都做了什么。
2)更好的管理Activity的生命周期。
3)了解Activity的启动可以更好的知道这个场景适合做哪些操作。
七、我遇到的疑惑
服务端接收到启动通知有返回再次通知客户端吗?我觉得没有