Android四大组件系列2 Activity启动流程(上)

一 概述

Activity 的启动分为不同进程间和相同进程内部的启动。由于进程间 Activity 启动流程包括了相同进程内部 Activity 启动的流程。因此本文只分析不同进程间,比如点击 Launcher 桌面图标启动 Activity 的整个过程。在阅读本篇文章之前,建议同学们先了解下 AMS 相关的数据结构和管理机制,可参考 Android四大组件系列1 AMS相关数据结构

时序图如下:
在这里插入图片描述
涉及代码如下:

frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
frameworks/base/services/core/java/com/android/server/wm/ActivityStartController.java
frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
frameworks/base/services/core/java/com/android/server/wm/ActivityStack.java
frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java
frameworks/base/services/core/java/com/android/server/wm/ActivityDisplay.java
frameworks/base/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
frameworks/base/services/core/java/com/android/server/wm/ClientLifecycleManager.java
 
frameworks/base/core/java/android/app/Activity.java
frameworks/base/core/java/android/app/Instrumentation.java
frameworks/base/core/java/android/app/ActivityTaskManager.java
frameworks/base/core/java/android/app/ActivityThread.java
frameworks/base/core/java/android/app/ContextImpl.java
frameworks/base/core/java/android/app/AppComponentFactory.java
frameworks/base/core/java/android/app/FragmentController.java
 
frameworks/base/core/java/android/app/ClientTransactionHandler.java
frameworks/base/core/java/android/app/servertransaction/ClientTransaction.java
frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java
frameworks/base/core/java/android/app/servertransaction/TransactionExecutorHelper.java
frameworks/base/core/java/android/app/servertransaction/ActivityLifecycleItem.java
frameworks/base/core/java/android/app/servertransaction/LaunchActivityItem.java

二 startActivity阶段

我们知道,我们可以在自己的应用中的 Activity 中通过 startActivity 就可以发送一个 Intent 然后启动一个新的应用,这里边调用的就是 Activity.startActivity,我们来看这个函数,需要注意的是这些个操作都是在发起端进程中执行的。这个发起端可以是 Launcher,也可以是任何调用 startActivity 的应用。

2.1 Activity.startActivity

frameworks/base/core/java/android/app/Activity.java

public void startActivity(Intent intent) {
   
   
        this.startActivity(intent, null);
}

public void startActivity(Intent intent, @Nullable Bundle options) {
   
   
        if (options != null) {
   
   
            startActivityForResult(intent, -1, options);
        } else {
   
              
            startActivityForResult(intent, -1);
        }
}

2.2 Activity.startActivityForResult

public void startActivityForResult(@RequiresPermission Intent intent,
        int requestCode) {
   
    // 从当前应用进程跨进程跳转到了 AMS
        startActivityForResult(intent, requestCode, null);
}

public void startActivityForResult(@RequiresPermission Intent intent,
     int requestCode, @Nullable Bundle options) {
   
   
        if (mParent == null) {
   
   
            options = transferSpringboardActivityOptions(options);
            // 调用 Instrumentation 的 execStartActivity 方法,继续执行
            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());
            }
            if (requestCode >= 0) {
   
   
                mStartedActivity = true;
            }
            ......
        } else {
   
   
            ......
        }
    }

2.3 Instrumentation.execStartActivity

frameworks/base/core/java/android/app/Instrumentation.java

public ActivityResult execStartActivity(
    Context who, IBinder contextThread, ......) {
   
   
    IApplicationThread whoThread = (IApplicationThread) contextThread;
        ......
        try {
   
   
            ......
            // 跨进程调用 ActivityTaskManagerService.startActivity
            int result = ActivityTaskManager.getService()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                    intent.resolveTypeIfNeeded(who.getContentResolver()),
                    token, target != null ? target.mEmbeddedID : null,
                    requestCode, 0, null, options);
            // 检查 result, 判断 Activity 是否启动成功.
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
   
   
            throw new RuntimeException("Failure from system", e);
        }
        return null;
    }
  • who:启动 Activity 的上下文
  • contextThread:ActivityThread 中的 ApplicationThread 对象 mAppThread
  • token:令牌,标识着 Activity,系统唯一标识
  • target:在哪个 Activity 中启动,会接收启动完成的结果
  • intent:启动意图
  • requestCode:请求码,用于将结果和请求对应上
  • options:可选参数

execStartActivity 里面我们需要重点关注两个参数。

mMainThread.getApplicationThread() 会返回一个 ApplicationThread 类型的变量。这个变量我们在 Android四大组件系列1 AMS相关数据结构 中已经介绍过,这里 ApplicationThread 代表的是发起请求的客户端进程,后面 AMS 就是通过它来和客户端进程进行跨进程通信的。

第二个需要重点关注的就是 mToken,mToken 我们在之前也介绍过了,它是连接 ActivityRecord,Activity,ActivityClientRecord 的桥梁,AMS 通过它就可以获取客户端进程中的 Activity 的详细信息。

最后通过 Binder 调用 ActivityTaskManagerService 的 startActivity 函数,之前讲过 ATMS 是用来分担 AMS 的一些功能的。从这个地方开始就从当前应用进程跨进程跳转到了 AMS,接下来我们来看 AMS 是怎么处理响应的。

2.4 ActivityTaskManagerService.startActivity

frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java

public final int startActivity(IApplicationThread caller,
    String callingPackage, Intent intent, String resolvedType,
    IBinder resultTo, String resultWho, int requestCode, int startFlags,
    ProfilerInfo profilerInfo, Bundle bOptions) {
   
   
        // 指定启动 Activity 的 userId
        return startActivityAsUser(caller, callingPackage, intent,
            resolvedType, resultTo, resultWho, requestCode, startFlags,
            profilerInfo, bOptions, UserHandle.getCallingUserId());
}
    
public int startActivityAsUser(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo,
            String resultWho, int requestCode, int startFlags,
            ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
   
   
        // 继续调用 startActivityAsUser
        return startActivityAsUser(caller, callingPackage, intent,
            resolvedType, resultTo, resultWho, requestCode, startFlags,
            profilerInfo, bOptions, userId, true /*validateIncomingUser*/);
}

int startActivityAsUser(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo,
            String resultWho, int requestCode, int startFlags, 
            ProfilerInfo profilerInfo, Bundle bOptions, int userId,
            boolean validateIncomingUser) {
   
   
        // 确保调用进程不是 isolated
        enforceNotIsolatedCaller("startActivityAsUser");
        // 检查 userId 的有效性, 并返回有效的 userId
        userId = getActivityStartController().checkTargetUser(userId,
            validateIncomingUser, Binder.getCallingPid(),
            Binder.getCallingUid(), "startActivityAsUser");
        // ActivityStartController#obtainStarter(),拿到 ActivityStarter
        // ActivityStarter#execute(),启动 Activity
        return getActivityStartController().obtainStarter(intent,
           "startActivityAsUser")
                .setCaller(caller)
                .setCallingPackage(callingPackage)
                .setResolvedType(resolvedType)
                .setResultTo(resultTo)
                .setResultWho(resultWho)
                .setRequestCode(requestCode)
                .setStartFlags(startFlags)
                .setProfilerInfo(profilerInfo)
                .setActivityOptions(bOptions)
                .setMayWait(userId)
                .execute();
}

在 ATMS 的 startActivityAsUser 方法中会获取并初始化 ActivityStater 对象,然后调用它的 execute 方法,用来启动 Activity。注意倒数第二个 setMayWait() 方法,会将 mRequest.mayWait 属性设为 true。

ActivityStarter.java

ActivityStarter setMayWait(int userId) {
   
   
        mRequest.mayWait = true;
        mRequest.userId = userId;
        return this;
    }

2.5 ActivityStarter.execute

frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java

int execute() {
   
   
        try {
   
   
            if (mRequest.mayWait) {
   
   // 需要等待请求返回结果
                return startActivityMayWait(mRequest.caller, mRequest.callingUid,
                       mRequest.callingPackage, mRequest.realCallingPid,
                       ......);
            } else {
   
   
                return startActivity(mRequest.caller, mRequest.intent, 
                     mRequest.ephemeralIntent,  mRequest.resolvedType,
                     ......);
            }
        } finally {
   
   
            onExecutionComplete();// 执行完成
        }
    }

由上面的分析可知,这里的 mRequest.mayWait 为 true,是在上一步创建 ActivityStarter 实例时,通过调用 setMayWait 设置的。

2.6 ActivityStarter.startActivityMayWait

private int startActivityMayWait(IApplicationThread caller, int callingUid,
            ......) {
   
   
        ......
        // PakageManagerService 解析 intent(要启动的 APP 的 intent),
        // 获取 Activity 更多的信息
        ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType,
            userId, 0 /* matchFlags */,
            computeResolveFilterUid(
            callingUid, realCallingUid, mRequest.filterCallingUid));
        ......
        // Collect information about the target of the Intent.
        ActivityInfo aInfo = mSupervisor.resolveActivity(
                intent, rInfo, startFlags, profilerInfo);
        synchronized (mService.mGlobalLock) {
   
   
            ......
            final ActivityRecord[] outRecord = new ActivityRecord[1];
            // 调用 startActivity
            int res = startActivity(caller, intent, ephemeralIntent,
                ......);
            ......
            return res;
        }
}

</

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值