framework | Activity启动流程(android-31)

·  阅读 2499
framework | Activity启动流程(android-31)

前言

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第5天,点击查看活动详情

很多应用层开发者包括我一开始都觉得开发上层应用为什么要了解这些关于系统代码的知识,其实作为应用层开发了解一些framework层的代码是非常有必要的,我总结大概有如下几点:

  1. 了解系统组件工作机制,有助于我们解决问题,毕竟我们平时用的四大组件都是系统给我们创建好的,了解了系统组件工作机制,至少在看问题日志的调用栈可以更加清晰。
  2. Android作为Linux上一款非常优秀的操作系统,学习Android操作系统,可以提高我们对操作系统在实现上的理解,可以让我们的技术更进一步。

本篇文章就从我们非常熟悉的Activity入手,Activity作为一个展示型组件,用于直接向用户展示一个界面,同时可以接收用户的输入信息从而进行交互,可以说Activity组件是一个App的核心,毕竟其他组件都是在后台工作。

本篇文章的源码是android-31,不方便查看源码的可以参考下面在线网址:

aospxref.com/android-12.…

文中涉及的时序图,由于掘金编辑器的限制,可以放大网页查看。

正文

因为Activity的启动涉及到跨进程,所以这里我们分为启动端即客户端和服务端来分析,而对于使用隐式Intent启动Activity,被启动的Activity所在的进程可能没有启动,所以这里可以分为进程已经存在和进程不存在这俩种情况分析。

客户端

我们在Activity中使用如下代码开启一个新Activity:

startActivity(Intent(this, SecondActivity::class.java)
复制代码

这里调用链路如下(下面方法均为Activity中方法):

public void startActivity(Intent intent)
复制代码
public void startActivity(Intent intent, @Nullable Bundle options)
复制代码
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
        @Nullable Bundle options)
复制代码

一般启动Activity都会调用到startActivityForResult方法上,看一下该方法:

//启动一个activity并且在其结束时返回一个result
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
        @Nullable Bundle options) {
    if (mParent == null) {
        ...
        //调用Instrumentation的execStartActity方法
        Instrumentation.ActivityResult ar =
            mInstrumentation.execStartActivity(
                this, mMainThread.getApplicationThread(), mToken, this,
                intent, requestCode, options);
        if (ar != null) {
            //分析启动的结果
            mMainThread.sendActivityResult(
                mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                ar.getResultData());
        }
        ...
    } else {
        ...
    }
}
复制代码

上述方法的核心是调用Instrumentation的execStartActivity方法,其实其他调用链启动activity,最后都会调用这个方法,当调用完启动方法,会得到启动结果ar,我们看一下该方法定义:

public ActivityResult execStartActivity(
        Context who, IBinder contextThread, IBinder token, Activity target,
        Intent intent, int requestCode, Bundle options)
复制代码

可以发现第2和第3个参数是IBinder类型,而IBinder接口是远程对象的基础接口,其实现类是Binder,该类型的对象是具有跨进程通信的能力,其中第2个参数是mMainThread.getApplicationThread(),我们来看一下该类:

public final class ActivityThread extends ClientTransactionHandler
        implements ActivityThreadInternal
复制代码

而ApplicationThread则是该类的内部类:

private class ApplicationThread extends IApplicationThread.Stub
复制代码

可以发现该类继承至IApplicationThread.Stub类,这里就涉及到了AIDL知识,这里信息如下:

类/文件位置作用
IApplicationThread.aidl/frameworks/base/core/java/android/app/IApplicationThread.aidl该aidl是App进程中定义的接口,这些接口是会被系统进程所调用,从AIDL的C/S端来看,这个就是服务端,用来响应系统进程的操作
IApplicationThread.java/该类是一个接口,是aidl生成的Java类,里面定义了上面aidl文件中定义的需要IPC的接口
IApplicationThread.Stub.java/该类是一个Java类,实现了IApplicationThread.java接口,同时继承至Binder,其内部有transact()等方法,利用Binder机制可以进行IPC
ApplicationThread.java/frameworks/base/core/java/android/app/ActivityThread$ApplicationThread.java该类就是服务端IApplicationThread.aidl接口的具体实现,当系统进程进行远程调用时,该类方法会执行

通过上述我们知道ApplicationThread实例其实就是应用进程的服务端,用于被系统进程远程调用的。接着分析,这里我们可以发现ApplicationThread是ActivityThread的内部类,该类实例和Instrumentation实例均为Activity中的变量,下面对这里涉及到的俩个类做个简单总结:

位置简介
ActivityThread/frameworks/base/core/java/android/app/ActivityThread.java该类管理着一个应用进程主线程的执行,比如调度和执行activity、广播等,即应用的主线程中的组件逻辑都有该类负责
Instrumentation/frameworks/base/core/java/android/app/Instrumentation.java该类主要作用是组件的运行追踪,所以该类中会有启动activity、调用activity生命周期等方法,可以看成是运行过程的帮助类

类对象实例关系大概如下:

classDiagram
Activity --> ActivityThread
Activity --> Instrumentation
ActivityThread --> ApplicationThread
Activity : ActivityThread mMainThread
Activity : Instrumentation mInstrumentation
class ActivityThread{
ApplicationThread mAppThread
}
class Instrumentation{
execStartActivity()
}
class ApplicationThread{
bindApplication()
}

而Activity中变量的赋值是在Activity的attach()方法中进行:

//对Activity中变量进行赋值,比如ActivityThread对象,token等
final void attach(Context context, ActivityThread aThread,
        Instrumentation instr, IBinder token, int ident,
        Application application, Intent intent, ActivityInfo info,
        CharSequence title, Activity parent, String id,
        NonConfigurationInstances lastNonConfigurationInstances,
        Configuration config, String referrer, IVoiceInteractor voiceInteractor,
        Window window, ActivityConfigCallback activityConfigCallback, IBinder assistToken,
        IBinder shareableActivityToken)
复制代码

上面几个类我们必须要混个脸熟,现在我们继续分析Instrumentation中execStartActivity代码:

public ActivityResult execStartActivity(
        Context who, IBinder contextThread, IBinder token, Activity target,
        Intent intent, int requestCode, Bundle options) {
    //应用端的AIDL实现类    
    IApplicationThread whoThread = (IApplicationThread) contextThread;
    //激活所有的ActivityMonitor
    ...
    try {
        intent.migrateExtraStreamToClipData(who);
        intent.prepareToLeaveProcess(who);
        //IPC通信
        int result = ActivityTaskManager.getService().startActivity(whoThread,
                who.getOpPackageName(), who.getAttributionTag(), 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;
}
复制代码

在该方法中首先是激活所有ActivityMonitor即监听器,这个我们不做讨论,重点是进行了IPC通信,这里的代码如下:

//获取IActivityTaskManager实例
public static IActivityTaskManager getService() {
    return IActivityTaskManagerSingleton.get();
}
复制代码
//获取单例
private static final Singleton<IActivityTaskManager> IActivityTaskManagerSingleton =
        new Singleton<IActivityTaskManager>() {
            @Override
            protected IActivityTaskManager create() {
                //返回一个IBinder对象
                final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE);
                //转成IActivityTaskManager
                return IActivityTaskManager.Stub.asInterface(b);
            }
        };
复制代码

简单来说这里就是获取到系统进程中的ActivityTaskManagerService实例,当然不是真的实例,而是一个Binder引用。

当然这里不能简单的一句话盖过,这里进行了IPC通信,这时就涉及了俩个进程:

进程描述
APP进程即每个应用默认不开启多进程模式,就是一个进程
system_server进程系统服务进程,该进程非常重要,会在Android系统启动时创建,它里面运行的就是系统服务。比如和Activity相关的ActivityTaskManagerService,和Window相关的WindowManagerService等等

由于系统服务特别多,在系统启动时就会有80多个,那如何进行调用呢?其实从文件名就可以区分和识别,比如启动Activity就涉及的相关类如下:

类/文件位置作用
IActivityTaskManager.aidl/frameworks/base/core/java/android/app/IActivityTaskManager.aidlAIDL文件,即ATMS所实现的接口,里面包括启动Activity等方法定义
ActivityTaskManager.java(ATM)/frameworks/base/core/java/android/app/ActivityTaskManager.java该类负责管理Activity的信息和交互,包括堆栈、显示等,这个在应用端被调用,但是该类的真实调用却是通过IPC获取到ATMS进行的,典型的桥接模式
ActivityTaskManagerService.java(ATMS)/frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java该类运行在系统的system_service进程中,其继承至IActivityTaskManager.Stub类,是AIDL的服务端,同时也是ATM的真正实现地方

我们可以推断出比如在客户端使用XXManager,其真实实现就是系统进程中的XXManagerService,而IXXManager.aidl就是AIDL接口,里面定义了能IPC的接口。

我们接着看上面那段获取ATMS的代码:

//返回一个IBinder对象 
final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE); 
//转成IActivityTaskManager 
return IActivityTaskManager.Stub.asInterface(b);
复制代码

这里的目的是拿到ATMS的Binder引用,而前面我们说的ATM真正实现也是拿到ATMS的Binder引用,我们看一下ATMS里的实现,然后一起说:

//ATM中的获取任务栈方法
public List<ActivityManager.RunningTaskInfo> getTasks(
        int maxNum, boolean filterOnlyVisibleRecents, boolean keepIntentExtra) {
    try {
        //桥接模式
        return getService().getTasks(maxNum, filterOnlyVisibleRecents, keepIntentExtra);
    } catch (RemoteException e) {
        throw e.rethrowFromSystemServer();
    }
}
复制代码
public static IActivityTaskManager getService() {
    return IActivityTaskManagerSingleton.get();
}
复制代码
//获取单例
private static final Singleton<IActivityTaskManager> IActivityTaskManagerSingleton =
        new Singleton<IActivityTaskManager>() {
            @Override
            protected IActivityTaskManager create() {
                final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE);
                return IActivityTaskManager.Stub.asInterface(b);
            }
        };
复制代码

这里会发现也是一样的方法获取ATMS引用然后转成我们需要的IActivityTaskManager类型,这里是通过ServiceManager(SM)类的静态方法getService来获取的,通过名字我们其实就可以知道这个类是专门管理服务的。

简单来说就是我们的服务当在注册时,会把信息给到SM来保存,这里只需要保存该服务名和对应的Binder,然后其他客户端想访问该服务时,必须通过SM来查询,返回服务的Binder引用,这时就可以通过该Binder引用进行后续的数据查询了。

大致如下图:

sequenceDiagram
服务 ->> ServiceManager:注册(服务名和Binder)
Note left of ServiceManager:保存服务和Binder
客户端->>ServiceManager: 获取服务(服务名)
Note right of ServiceManager:根据服务名,获取Binder引用BinderProxy
ServiceManager->>客户端: 返回BinderProxy
客户端 ->> 服务: 开始通信

经过SM的努力,以及IPC通信,最终的startActivity方法就是调用的是ATMS中的方法。这里我们可以简单做个总结:

sequenceDiagram
participant ACT as Activity
participant Ins as Instrumentation
participant ATM as ActivityTaskManager
participant SM as ServiceManager
participant ATMS as ActivityTaskManagerService
ACT -->> Ins: startActivity(Intent intent)
ACT -->> Ins:startActivity(intent, null)
ACT -->> Ins:startActivityForResult
ACT ->> Ins:execStartActivity
Ins ->> ATM:getService()

ATMS ->> SM:注册(早已发生,提供Binder)
ATM ->> SM:getService(Context.ACTIVITY_TASK_SERVICE)
SM ->> ATM:返回ATMS的BinderProxy
ATM ->> Ins:返回ATMS的Binder引用
Ins ->> ATMS:调用系统进程中ATMS的startActivity

服务端

到这里,这个启动Activity的请求就到了系统进程,我们看一下ATMS中调用链如下:

startActivity()
复制代码
startActivityAsUser()
复制代码

这里看一下该方法:

private int startActivityAsUser(IApplicationThread caller, String callingPackage,
        @Nullable String callingFeatureId, Intent intent, String resolvedType,
        IBinder resultTo, String resultWho, int requestCode, int startFlags,
        ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) {
    ...
    //把启动流程移交给ActivityStarter
    return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
            .setCaller(caller)
            .setCallingPackage(callingPackage)
            .setCallingFeatureId(callingFeatureId)
            .setResolvedType(resolvedType)
            .setResultTo(resultTo)
            .setResultWho(resultWho)
            .setRequestCode(requestCode)
            .setStartFlags(startFlags)
            .setProfilerInfo(profilerInfo)
            .setActivityOptions(bOptions)
            .setUserId(userId)
            .execute();

}
复制代码

这里为了解耦,在ATMS中,把启动activity的逻辑都封装到ActivityStarter,该类的作用是包含了所有启动相关的逻辑,比如intent参数解析、flag转换以及任务栈等,所以我们直接就看该类的execute()方法调用链:

//处理一些必要的信息,同时开启启动activity的"愉快之旅"
int execute() {
    try {
        ...
        //执行请求
        res = executeRequest(mRequest);
        ...
    } finally {
        onExecutionComplete();
    }
}
复制代码
//执行启动activity请求,并且在开始之前做一些简单的检察
private int executeRequest(Request request) {
    ...
    //记录Activity信息
    final ActivityRecord r = new ActivityRecord.Builder(mService)
            .setCaller(callerApp)
            .setLaunchedFromPid(callingPid)
            .setLaunchedFromUid(callingUid)
            .setLaunchedFromPackage(callingPackage)
            .setLaunchedFromFeature(callingFeatureId)
            .setIntent(intent)
            .setResolvedType(resolvedType)
            .setActivityInfo(aInfo)
            .setConfiguration(mService.getGlobalConfiguration())
            .setResultTo(resultRecord)
            .setResultWho(resultWho)
            .setRequestCode(requestCode)
            .setComponentSpecified(request.componentSpecified)
            .setRootVoiceInteraction(voiceSession != null)
            .setActivityOptions(checkedOptions)
            .setSourceRecord(sourceRecord)
            .build();
    ...
    //启动activity
    mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
            request.voiceInteractor, startFlags, true /* doResume */, checkedOptions, inTask,
            restrictedBgActivity, intentGrants);
    ...
}
复制代码
//在完成大部分初步检查并且确定调用者有必要的权限后开始启动活动
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, Task inTask,
            boolean restrictedBgActivity, NeededUriGrants intentGrants) {
    ...
    //根据原始的intent创建一个Transition实例
    final Transition newTransition = (!mService.getTransitionController().isCollecting()
            && mService.getTransitionController().getTransitionPlayer() != null)
            ? mService.getTransitionController().createTransition(TRANSIT_OPEN) : null;
    IRemoteTransition remoteTransition = r.takeRemoteTransition();
    if (newTransition != null && remoteTransition != null) {
        newTransition.setRemoteTransition(remoteTransition);
    }
    mService.getTransitionController().collect(r);
    try {
        ...
        //核心方法
        result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
                startFlags, doResume, options, inTask, restrictedBgActivity, intentGrants);
    } finally {
       ...
    }
    ...
}
复制代码
//启动一个Activity并且确定该Activity是应该添加到现有的任务栈栈顶,或者将intent发送给已存在的activity
//即可,同时还将activity的任务栈调度到有效的task和display上
int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
        int startFlags, boolean doResume, ActivityOptions options, Task inTask,
        boolean restrictedBgActivity, NeededUriGrants intentGrants) {
    ...
    //判断是否需要为当前Activity创建Task等逻辑
    mTargetRootTask.startActivityLocked(mStartActivity,
            topRootTask != null ? topRootTask.getTopNonFinishingActivity() : null, newTask,
            mKeepCurTransition, mOptions, sourceRecord);
    if (mDoResume) {
        ...
        //核心方法
        mRootWindowContainer.resumeFocusedTasksTopActivities(
                    mTargetRootTask, mStartActivity, mOptions, mTransientLaunch);
        }
    }
    ...
}
复制代码

这里调用到RootWindowContainer.java中

boolean resumeFocusedTasksTopActivities(
        Task targetRootTask, ActivityRecord target, ActivityOptions targetOptions,
        boolean deferPause) {
        ...
    result |= focusedRoot.resumeTopActivityUncheckedLocked(target, targetOptions);
 ...

    return result;
}
复制代码

这里调用到Task.java中

boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options,
        boolean deferPause) {
            ...
            someActivityResumed = resumeTopActivityInnerLocked(prev, options, deferPause)
            return someActivityResumed;
        }   
}
复制代码
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options,
        boolean deferPause) {
    ...
    mTaskSupervisor.startSpecificActivity(next, true, false);
    ...   
    return true;
}
复制代码

跳转到ActivityTaskSupervisor.java

void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) {
    //Activity所在的Application是否在运行
    final WindowProcessController wpc =
            mService.getProcessController(r.processName, r.info.applicationInfo.uid);

    boolean knownToBeDead = false;
    if (wpc != null && wpc.hasThread()) {
        try {
            //进程已经存在
            realStartActivityLocked(r, wpc, andResume, checkConfig);
            return;
        } catch (RemoteException e) {
            Slog.w(TAG, "Exception when starting activity "
                    + r.intent.getComponent().flattenToShortString(), e);
        }
        knownToBeDead = true;
    }
    //进程不存在,启动进程
    mService.startProcessAsync(r, knownToBeDead, isTop, isTop ? "top-activity" : "activity");
}
复制代码

上面逻辑非常多,而且调用特别多,其实不用深入理解,这些代码主要作用就是由系统来统一管理Activity,比如Activity的任务栈、状态等,这样做的好处就是系统可以统筹全局,系统包含所有activity的信息,这样在我们进行页面跳转或者跨应用调用时逻辑就好管理。

上面的调用链关系如下:

sequenceDiagram
客户端->>ATMS:远程调用startActivity()
ATMS-->>ATMS: startActivity()
ATMS-->>ATMS: startActivityAsUser()
ATMS->>ActivityStarter: execute()
ActivityStarter-->>ActivityStarter:executeRequest
ActivityStarter-->>ActivityStarter:startActivityUnchecked
ActivityStarter-->>ActivityStarter:startActivityInner
ActivityStarter->>Task:startActivityLocked
ActivityStarter->>RootWindowContainer:resumeFocusedTasksTopActivities
RootWindowContainer->>Task:resumeTopActivityUncheckedLocked
Task-->>Task:resumeTopActivityInnerLocked
Task->>ActivityTaskSupervisor:startSpecificActivity
ActivityTaskSupervisor->>已存在进程:启动activity
ActivityTaskSupervisor->>进程不存在:新建进程

上面代码主要逻辑就是系统服务统一管理和保存Activity信息,下面我们将分俩方面继续分析,即需要启动的activity所在的进程已经启动和没有启动的情况。

进程已经启动

在前面代码分析中,在startSpecificActivity方法中,当要启动的Activity存在时调用realStartActivityLocked方法:

boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
        boolean andResume, boolean checkConfig) throws RemoteException {

            //创建启动Activity的事务
            final ClientTransaction clientTransaction = ClientTransaction.obtain(
                    proc.getThread(), r.appToken);
            //添加Callback
            final boolean isTransitionForward = r.isTransitionForward();
            clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
                    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, proc.getReportedProcState(),
                    r.getSavedState(), r.getPersistentSavedState(), results, newIntents,
                    r.takeOptions(), isTransitionForward,
                    proc.createProfilerInfoIfNeeded(), r.assistToken, activityClientController,
                    r.createFixedRotationAdjustmentsIfNeeded(), r.shareableActivityToken,
                    r.getLaunchedFromBubble()));

            //生命周期对象
            final ActivityLifecycleItem lifecycleItem;
            if (andResume) {
                lifecycleItem = ResumeActivityItem.obtain(isTransitionForward);
            } else {
                lifecycleItem = PauseActivityItem.obtain();
            }
            //设置生命周期请求
            clientTransaction.setLifecycleStateRequest(lifecycleItem);
            //执行事务
            mService.getLifecycleManager().scheduleTransaction(clientTransaction);
           ...
           return true;
}
复制代码

上面核心代码就是这个创建事务实例以及利用该实例来进行启动Activity,我们来看看是如何进行的。首先这里有俩个类要熟悉一下:

位置作用
ClientTransaction/frameworks/base/core/java/android/app/servertransaction/ClientTransaction.java它是一个容器,包含这一系列的消息,这些消息回被发送到客户端。而这些消息包括一系列回调和一个最终的生命周期状态
ActivityLifecycleItem /frameworks/base/core/java/android/app/servertransaction/ActivityLifecycleItem.java包含Activity的生命周期,是一个activity应该达到某种生命周期的请求
ClientLifecycleManager/frameworks/base/services/core/java/com/android/server/wm/ClientLifecycleManager.java用来执行事务的

所以这里的核心逻辑就到了scheduleTransaction方法:

void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
        //这里是IApplicationThread类型,也就是我们最开始说的用来被系统进程调用的接口,其实现
        //运行在APP进程
        final IApplicationThread client = transaction.getClient();
        //执行事务
        transaction.schedule();
          if (!(client instanceof Binder)) {
              transaction.recycle();
         }
       }
复制代码

这里的核心方法就是schedule():

public void schedule() throws RemoteException {
          mClient.scheduleTransaction(this);
}
复制代码

这里的this就是ClientTransaction实例,而mClient就是IApplicationThread实例,所以这个调用是一个IPC,我们这里直接回到APP进程,还记得前面我们所的该接口在哪个类实现吗?没错,就是ActivityThread的内部类ApplicationThread:

//ApplicationThread中方法
@Override
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
    ActivityThread.this.scheduleTransaction(transaction);
}
复制代码

这里调用的是ActivityThread.this的方法,我们可以看一下该方法定义在ActivityThread的父类ClientTransactionHandler中:

public final class ActivityThread extends ClientTransactionHandler
复制代码
void scheduleTransaction(ClientTransaction transaction) {
    //预处理
    transaction.preExecute(this);
    //处理事务
    sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
复制代码

这里其实就是利用Handler发送消息了,而该Handler定义的地方就是ActivityThread类中的内部类:H,我们通过message找到处理该消息的地方:

//ActivityThread$H
case EXECUTE_TRANSACTION:
    final ClientTransaction transaction = (ClientTransaction) msg.obj;
    mTransactionExecutor.execute(transaction);
    if (isSystem()) {
        transaction.recycle();
    }
    break;
复制代码

这里会利用mTransactionExecutor来执行这个事务实例,该类位置:

/frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java

该类实例是在ActivityThread中通过构造函数所得:

private final TransactionExecutor mTransactionExecutor = new TransactionExecutor(this);
复制代码

然后是该实例的execute方法:

//处理事务,首先所有的callbacks都会按序执行,然后client会切换到给定的state
public void execute(ClientTransaction transaction) {
    ...
    //执行回调
    executeCallbacks(transaction);
    //切换生命周期状态
    executeLifecycleState(transaction);
    mPendingActions.clear();
    if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "End resolving transaction");
}
复制代码
//处理生命周期状态
private void executeLifecycleState(ClientTransaction transaction) {
          final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
          if (lifecycleItem == null) {
              // No lifecycle request, return early.
              return;
          }
          final IBinder token = transaction.getActivityToken();
          final ActivityClientRecord r = mTransactionHandler.getActivityClient(token);
          //切换到期望的生命周期
          cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */, transaction);
         lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
         lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
}
复制代码
private void cycleToPath(ActivityClientRecord r, int finish, boolean excludeLastState,
             ClientTransaction transaction) {
          final int start = r.getLifecycleState();
          final IntArray path = mHelper.getLifecyclePath(start, finish, excludeLastState);
          //执行生命周期序列
          performLifecycleSequence(r, path, transaction);
      }
复制代码
//真正调用的地方
private void performLifecycleSequence(ActivityClientRecord r, IntArray path,
              ClientTransaction transaction) {
          final int size = path.size();
          for (int i = 0, state; i < size; i++) {
              state = path.get(i);
              switch (state) {
                  case ON_CREATE:
                      //由于新启动的Activity,默认会先执行ON_CREATE
                      mTransactionHandler.handleLaunchActivity(r, mPendingActions,null );
                      break;
                  case ON_START:
                      mTransactionHandler.handleStartActivity(r, mPendingActions,null);
                      break;
                  case ON_RESUME:
                      mTransactionHandler.handleResumeActivity(r, false ,
                             r.isForward, "LIFECYCLER_RESUME_ACTIVITY");
                      break;
                  case ON_PAUSE:
                      mTransactionHandler.handlePauseActivity(r, false ,
                             false, 0 , mPendingActions,
                              "LIFECYCLER_PAUSE_ACTIVITY");
                      break;
                  case ON_STOP:
                      mTransactionHandler.handleStopActivity(r, 0 ,
                              mPendingActions, false ,
                              "LIFECYCLER_STOP_ACTIVITY");
                     break;
                  case ON_DESTROY:
                      mTransactionHandler.handleDestroyActivity(r, false ,
                              0 , false ,
                              "performLifecycleSequence. cycling to:" + path.get(size - 1));
                      break;
                  case ON_RESTART:
                      mTransactionHandler.performRestartActivity(r, false );
                      break;
                  default:
                      throw new IllegalArgumentException("Unexpected lifecycle state: " + state);
             }
          }
复制代码

还记得前面说的该方法构造函数中的参数吗,这里的mTransactionHandler实例就是我们熟悉的ActivityThread实例,所以按照调用这里会调用其handleLaunchActivity()方法,到这里我们来简单梳理一下调用流程:

sequenceDiagram
participant ATS as ActivityTaskSupervisor
participant TRANS as ClientTransaction
participant IAP as IApplicationThread
participant AT as ActivityThread
participant CTH as ClientTransactionHandler
participant AT.H as ActivityThread$H
participant TransactionExecutor as TransactionExecutor

ATS->>TRANS: realStartActivityLocked
Note right of ATS:进程存在情况下,启动Activity
TRANS->>IAP:schedule()
IAP->>AT:scheduleTransaction()
Note left of AT:远程调用,回到APP进程
AT->>CTH:scheduleTransaction()
CTH->>AT.H:sendMessage(EXECUTE_TRANSACTION)
AT.H->>TransactionExecutor:execute()
Note right of AT.H:系统记录状态
TransactionExecutor->>TransactionExecutor:executeLifecycleState()
TransactionExecutor->>TransactionExecutor:cycleToPath()
TransactionExecutor->>TransactionExecutor:performLifecycleSequence()
TransactionExecutor->>AT:handleLaunchActivity()
Note right of AT:APP进程开始处理

看完上面流程后,我们可以看到Android系统设计的严谨,更可以看出系统服务统筹和管理的功能,接下来就剩最后一步了,我们来看看在ActivityThread中是如何处理Activity的:

public Activity handleLaunchActivity(ActivityClientRecord r,
        PendingTransactionActions pendingActions, Intent customIntent) {
    ...    
    //得到Activity实例
    final Activity a = performLaunchActivity(r, customIntent);
    ...
}
复制代码
//创建Activity核心方法
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    ActivityInfo aInfo = r.activityInfo;
    ...
    //创建appContext
    ContextImpl appContext = createBaseContextForActivity(r);
    Activity activity = null;
    try {
        //得到activity实例
        java.lang.ClassLoader cl = appContext.getClassLoader();
        activity = mInstrumentation.newActivity(
                cl, component.getClassName(), r.intent);
        ...
    } catch (Exception e) {
       ...
    }

    try {
        //如果不存在Application,则创建
        Application app = r.packageInfo.makeApplication(false, mInstrumentation);

        if (activity != null) {
            ...
            Window window = null;
            ...
            //加载资源
            appContext.getResources().addLoaders(
                    app.getResources().getLoaders().toArray(new ResourcesLoader[0]));
            //调用attach方法
            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,
                    r.assistToken, r.shareableActivityToken);

           ...
            if (r.isPersistable()) {
                //回调onCreate方法
                mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
            } else {
                mInstrumentation.callActivityOnCreate(activity, r.state);
            }
        ...
        }
       ...
    return activity;
}
复制代码

该方法是创建Activity的核心方法,包括了我们熟知的诸多逻辑,这里我们就不细看了,简单做个总结:

sequenceDiagram
ActivityThread->>Instrumentation: newActivity
ActivityThread-->>LoadApk:makeApplication
LoadApk-->>Instrumentation:callApplicationOnCreate
ActivityThread->>Instrumentation:callActivityOnCreate
Instrumentation->>Activity:performCreate
Note right of Activity:onCreate

这里最后还是由我们的老朋友Instrumentation调用Activity的performCreate方法来完成的创建。

这里我们来说几个常用的细节点:

  1. 从Activity启动流程可以看出Application的onCreate只会调用一次,而且早于Activity、Service和Receiver执行,但是ContentProvider是个例外,ContentProvider的注册在回调Application的onCreate之前。
  2. 在Activity的attach方法中,会赋值其他Activity传过来的很多值,包括token、ActivityThread实例等,同时会在该方法中执行Window相关的内容,进行绘制,这个在之前文章有介绍。

进程未启动

我们启动Activity同样可以启动其他没有打开的APP,这时就涉及系统需要先拉起一个新的APP进程,这部分内容有较多涉及系统进程,等下篇文章说完Android系统的启动再做具体分析。

总结

其实对于启动流程来说,如果不是专门的framework开发者来说,不必深入太细节,因为里面东西真是太多了。但是通过梳理流程,可以让我们对Android系统运行机制更加了解,便于我们解决应用层问题。

分类:
Android
标签:
收藏成功!
已添加到「」, 点击更改