Activity的启动分析

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sliverbullets/article/details/80766000

Activity的启动分析

一、什么是Activity的启动和名词解释

什么是:

在后面的解析过程中会遇到很多生类(单词)这里把它们列出来(其中大多数描述也是来自其他博客):
ActivityMangerServices 简称AMS,服务端对象,负责系统中所有Activity的生命周期。AMS是作为管理Android系统组件的核心服务,他在SystemServer执行run()方法的时候被创建,并运行在独立的进程中。具体来说就是SystemServer管理着Android中所有的系统服务,这些系统服务的生命周期回调都由System Server去调度负责。

ActivityThread App的真正入口。当开启App之后,会调用main()方法,开启消息循环列表,运行在主线程上。与ActivityManagerSevices配合,一起完成Activity的管理工作。

ApplicationThreadActivityThread的一个内部类 ,用来实现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的启动可以更好的知道这个场景适合做哪些操作。

七、我遇到的疑惑
服务端接收到启动通知有返回再次通知客户端吗?我觉得没有

一个不错的activity讲解参考

猜你喜欢

转载自blog.csdn.net/sliverbullets/article/details/80766000