基于Android-28 的源码 Activity 启动流程分析

本文深入剖析Android 28中Activity的启动流程,涉及关键类如Instrumentation、ActivityManagerService和ActivityStackSupervisor。通过启动方式、重要类分析、进程阶段划分三个方面,详细解释从启动请求到Activity实际运行的全过程,涵盖AMS中的ActivityRecord、TaskRecord和ActivityStack管理。
摘要由CSDN通过智能技术生成

之前介绍了Android IPC通信机制 Binder,接下来开始梳理Activity启动流程。

常见的Activity的启动有两种方式:
  1. 通过LaunchActivity启动一个应用,启动Activity。
  2. 通过同一个进程内的startActivity。

以下是基于Android 28的源码进行分析,顺便说一个AS很好用的快捷键:ctrl+shift+N 搜索打开文件

在接下来的流程中重要的几个类:
  1. Instrumentation:每个应用程序都有一个Instrumentation,每个Actviity持有它的引用,ActivityThread要创建或暂停Activity时,都是通过Instrumentation进行操作。

  2. ActivityManagerService:SystemServer中启动的独立进程,负责管理四大组件,可以利用binder跟它通信

  3. ActivityStarter:负责处理intenth和flags、选择启动的task、复用Activity等逻辑。

  4. ActivityRecord:每个Activity在AMS中对应一个ActivityRecod,记录Acitivty的信息

  5. TaskRecord:就是我们所讲的任务栈,先进后出,存储ActivityRecord

  6. ActivityStack:用来管理TaskRecord,ActivityStack是由ActivityStackSupervisor创建的

  7. ActivityStackSupervisor:AMS通过ActivityStackSupervisor负责操作ActivityStack

  8. ApplicationThread:ActivityThread的内部类,是一个binder对象,是ActivityManagerService向ActivityThread通信的桥梁。

  9. ActivityThread:表示APP的主线程,有main函数,

  10. ClientLifecycleManager:调用ClientTransaction,让AMS切换到APP进程执行生命周期

从进程的角度分析,可以把Activity的启动流程分成三个阶段:
  1. LauncherActivity或原活动的Activity进程

  2. AMS进程,真正启动Activity

  3. .从AMS到ApplicationThread所在的目标Activity进程,可能跟原活动的Activity进程同一个或者不同进程

在这里插入图片描述

1. LauncherActivity或原活动的Activity进程

一般我们从Activity的startActivity()或者Context的startActivity(),之所以把他们分开看,是在Android 28有一些不一样,但最后的走向是一样的。

先看下Context.startActivity(),其中Context的实现是在ContextImpl;

// ContextImpl
public void startActivity(Intent intent) {
   
    warnIfCallingFromSystemProcess();
    startActivity(intent, null);
}

public void startActivity(Intent intent, Bundle options) {
   
	...
	mMainThread.getInstrumentation().execStartActivity(
                getOuterContext(), mMainThread.getApplicationThread(), null,
                (Activity) null, intent, -1, options);
}

其中mMainThread是ActivityThread,最后转化到Instrumentation.execStartActivity()来启动Activity。

再看一下Activity的startActivity(),其实都是走到了startActivityForResult(),其中requestCode是-1;

// Activity
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
            @Nullable Bundle options) {
   
	if (mParent == null) {
   // mParent代表ActivityGroup,已经被废弃
		 Instrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode, options);
		 ...
	} 
	...
}

可见最后还是通过Instrumentation的execStartActivity()启动Activity。

mMainThread是ActivityThread,mMainThread.getApplicationThread()是ActivityThread的内部类ApplicationThread,他是一个IBinder。主要用于ActivityThread与AMS的通信。

// Instrumentation
public ActivityResult execStartActivity(
       Context who, IBinder contextThread, IBinder token, Activity target,
       Intent intent, int requestCode, Bundle options) {
   
    ...
	int result = ActivityManager.getService()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options);
	...
}

// ActivityManager
public static IActivityManager getService() {
   
    return IActivityManagerSingleton.get();
}

// ActivityManager
private static final Singleton<IActivityManager> IActivityManagerSingleton =
        new Singleton<IActivityManager>() {
   
            @Override
            protected IActivityManager create() {
   
                final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                final IActivityManager am = IActivityManager.Stub.asInterface(b);
                return am;
            }
        };

ActivityManager.getService() 获取得到的是IActivityManager的接口,这里涉及到ActivityManagerService(AMS),AMS运行在另外一个进程,继承了IBinder,是一个binder通信的Server端,而IActivityManagerSingleton实现了AMS Binder的client端,这样通过IActivityManagerSingleton就可以跟AMS通信。

2. AMS进程,真正启动Activity

最后ActivityManager.getService().startActivity()通过binder会走到AMS.startActivity();

// AMS
public final int startActivity(IApplicationThread caller, String callingPackage,
    Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
    int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
   
        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
                resultWho, requestCode, startFlags, profilerInfo, bOptions,
                UserHandle.getCallingUserId());
}

// AMS
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,
     boolean validateIncomingUser) {
   
     // userId是调用者,检查权限
     userId = mActivityStartController.checkTargetUser(userId, validateIncomingUser,
            Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
                
	 return mActivityStartController.obtainStarter(intent, "startActivityAsUser")
                .setCaller(caller)
                .setCallingPackage(callingPackage)
                .setResolvedType(resolvedType)
                .setResultTo(resultTo)
                .setResultWho
  • 7
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值