Android进阶之Activity启动流程

本文详细探讨了Android中Activity的启动过程,分为已启动应用进程启动Activity和未启动应用进程启动Activity两种情况。涉及关键组件如AMS、Instrumentation、ActivityThread等,详细阐述了从应用层发起请求到AMS处理,再到ActivityThread真正启动Activity的完整流程。
摘要由CSDN通过智能技术生成

Activity作为Android用户最重要的交互组件,是绝大部分App必不可少的一部分。本文从Activity::startActivityForResult为入口,基于Android8.1源码进行分析,理解Activity的启动流程。如有错漏之处,欢迎指出。

一. 概述

  Activity的启动方式有两种,一是在桌面上点击应用图标,一是在应用中调用函数启动Activity,实际上这两种方式最终都会调用的Activity的startActivityForResult函数。因此,本文以startActivityForResult为入口,对Activity的启动流程进行分析。Activity的启动又分为两种情况:一种是应用进程已启动的情况下启动Activity,另一种是在应用进程还没有启动时启动。下面将会分别按这两种情况进行分析。
  开始分析之前先来认识一下几个核心类:

  • ActivityManagerService:ActivityManagerService是系统的一个管理、调度服务,该服务由SystemService进程启动。应用进程以及四大组件的启动、切换、和调度都是由ActivityManagerService来控制的。
  • Instrumentation:是Android系统里的一套控制方法,类中提供了各种流程控制方法(例如:callActivityOnCreate()),Activity的生命周期就是通过该类来执行的。Instrumentation也可以用于自动化测试中。
  • ActivityStarter:该类是一个控制类,根据相关逻辑、Intent的flag等确定Activity应该如何启动以及关联相关的Task和stack。
  • ActivityThread:虽然类名中有一个Thread,但该类并不是一个线程类,该类依附于应用的主线程,也就是主线程,管理主线程的执行,通过IPC与AMS通信,调度和执行Activity、Broadcast等,以及管理其他的一些操作。
  • ApplicationThread:这个是ActivityThread的内部类,是一个Binder。ActivityThread通过该类与AMS进行IPC通信,是应用与AMS的通信桥梁。
  • ActivityStack:该类是用于记录一个Activity任务栈的状态,以及管理栈内的ActivityRecord。
  • ActivityStackSupervisor:该类是用来管理任务栈的,即管理ActivityStack。
  • ActivityRecord:该类是记录Activity相关信息的载体类,在ActivityManagerService中使用该类来管理Activity相关信息。
  • ActivityClientRecord:该类也是记录Activity相关信息的载体类,只不过该类是在ActivityThread中使用的,该类持有Activity对象实例。
  • TaskRecord:该类是任务栈信息记录载体类,包含若干个ActivityRecord,ActivityManagerService使用该类来确保Activity启动和退出的顺序。
  • ProcessRecord:该类是记录应用进程相关信息的载体类。

二. 应用进程已启动时启动Activity

  惯例先上流程图,这里的流程是在假定应用进程已经启动的情况下启动Activity(省略了一些细节,关注主要的处理代码)。我把Activity启动流程分为三段: 应用层发起请求、AMS处理请求、ActivityThread真正启动Activity。下面将按照这个分段进行分析。
启动Activity流程图

1. 应用层发起请求

  我们无论是通过调用startActivity()或者是直接调用startActivityForResult()函数发起启动Activity请求,最后都会通过Instrumentation::execStartActivity()函数进一步处理。在Instrumentation::execStartActivity()函数中会对Intent的数据做一些迁移处理,然后会调用IActivityManager接口函数startActivity() ,Binder远程调用到ActivityManagerService类的相应实现函数。到此,流程进入到AMS系统进程中。

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
            @Nullable Bundle options) {
   
     		... ...
            Instrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode, options);
           ... ... 
    }

 public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
   
        ... ... 
        if (referrer != null) {
   
            intent.putExtra(Intent.EXTRA_REFERRER, referrer);
        }
       ... ... 
        try {
   
            intent.migrateExtraStreamToClipData();//把EXTRA_STREAM等数据保存到clipdata中
            intent.prepareToLeaveProcess(who);
            //Binder远程调用AMS的startActivity函数
            int result = ActivityManager.getService()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options);
          .. ... 
    }
2. AMS处理请求

  启动请求来到ActivityManagerService后会添加上userId再把处理交给ActivityStarter::startActivityMayWait()。在该函数中首先会调用ActivityStackSupervisor::resolveIntent()获取能够响应该Intent的最佳Activity的ResolveInfo。如果有多个Activity能够响应该Intent且没有找到最优响应,则会返回ResolverActivity的ResolveInfo(具体实现这里不赘述,有兴趣的同学可自行查看源码,主要在PackageManagerService::chooseBestActivity()函数中判断最优响应目标),把所有可选Activity列出,让用户自行选择。为了更好的继续分析,这里直接假设找到了最优的响应Activity。根据获取的ResolveInfo调用ActivityStackSupervisor::resolveActivity()收集debug、track、profile等信息保存到ActivityManagerService中,开发者选项中的"Wait for debugger"就是在这里设置到ActivityManagerService的。

 final int startActivityMayWait(IApplicationThread caller, int callingUid,
            String callingPackage, Intent intent, String resolvedType,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode, int startFlags,
            ProfilerInfo profilerInfo, WaitResult outResult,
            Configuration globalConfig, Bundle bOptions, boolean ignoreTargetSecurity, int userId,
         TaskRecord inTask, String reason) {
   
         ... ... 
         //获取响应该Intent的相关信息
        ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId);
        ... ... 
        // Collect information about the target of the Intent.
        ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);

        	... ...

            final ActivityRecord[] outRecord = new ActivityRecord[1];
            int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,
                    aInfo, rInfo, voiceSession, voiceInteractor,
                    resultTo, resultWho, requestCode, callingPid,
                    callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
                    options, ignoreTargetSecurity, componentSpecified, outRecord, inTask,
                    reason);
        }
    }

  流程进入ActivityStarter::startActivityLocked()函数,记录启动Activity的理由和时间,然后调用ActivityStarter::startActivity()函数。该函数代码比较多,逻辑复杂,去掉一些判断逻辑,只分析主干。首先会通过ActivityStackSupervisor::checkStartAnyActivityPermission()函数判断是否获取到了启动Activity所需的权限,然后调用IntentFirewall::checkStartActivity()检查请求Intent是否被允许启动Activity (具体判断,兴趣的同学请自行分析源码)。当两者都为true时,继续往下执行,否则停止启动Activity。接着会创建ActivityRecord实例,该实例用于在ActivityManagerService中记录Activity相关的信息。doPendingActivityLaunchesLocked()函数处理一些延迟启动的Activity。

int startActivityLocked(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
            String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
            String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
            ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
            ActivityRecord[] outActivity, TaskRecord inTask, String reason) {
   
            ... ... 
        mLastStartReason = reason;
        mLastStartActivityTimeMs = System.currentTimeMillis();
        mLastStartActivityRecord[0] = null;

        mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
                aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
                callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
                options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
                inTask);
			... ...
    }
private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
            String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
            String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
            ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
            ActivityRecord[] outActivity, TaskRecord inTask) {
   
       ... ... 

        boolean abort = !mSupervisor.checkStartAnyActivityPermission(intent, aInfo, resultWho,
                requestCode, callingPid, callingUid, callingPackage, ignoreTargetSecurity, callerApp,
                resultRecord, resultStack, options);
        abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
                callingPid, resolvedType, aInfo.applicationInfo);

       ... ... 

        ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
                callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
                resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
                mSupervisor, options, sourceRecord);
       ... ... 
        doPendingActivityLaunchesLocked(false);

        return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true,
                options, inTask, outActivity);
    }

  接着进入到ActivityStarter::startActivity()函数中,设置布局推迟更新,然后继续调用ActivityStarter::startActivityUnchecked()。在函数中调用setInitialState(),首先先对ActivityStarter类的mStartActivity等属性进行初始化,获取task栈相关信息等以备后用。调用ActivityStarter::getReusableIntentActivity()函数判断是否可以复用已经保存在Task中Activity实例,如果可以就返回相应实例,否则返回null,例如Activity的launchMode是singleTask、singleInstance等情况。然后调用ActivityStarter::setTaskFromReuseOrCreateNewTask()函数,把ActivityRecord添加到TaskRecord中以及关联相应的ActivityStack,如果应用进程尚没有启动,则后续在进程启动后会根据这里记录启动Activity。接着是ActivityStackSupervisor::resumeFocusedStackTopActivityLocked(),判断是重新启动一个Activity还是就是当前的Top Activity。

/** ActivityStarter.java*/
private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
            ActivityRecord[] outActivity) {
   
        int result = START_CANCELED;
        try {
   
            mService.mWindowManager.deferSurfaceLayout();
            result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
                    startFlags, doResume, options, inTask, outActivity);
        ...  ...
    }
    
 private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
            ActivityRecord[] outActivity) {
   
		//初始化状态
        setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
                voiceInteractor);
        computeLaunchingTaskFlags();

        computeSourceStack();

        mIntent.setFlags(mLaunchFlags);

        ActivityRecord reusedActivity = getReusableIntentActivity();

      	... ... 
        if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
                && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
   
            newTask = true;
            String packageName= mService.mContext.getPackageName();
            if (mPerf != null) {
   
                mStartActivity.perfActivityBoostHandler =
                    mPerf.perfHint(BoostFramework.VENDOR_HINT_FIRST_LAUNCH_BOOST, packageName, -1, BoostFramework.Launch.BOOST_V1);
            }
            result = setTaskFromReuseOrCreateNewTask(
                    taskToAffiliate, preferredLaunchStackId, topStack);
        } else if (mSourceRecord != null) {
   
            result = setTaskFromSourceRecord();
        } else if (mInTask != null) {
   
            result = setTaskFromInTask();
        } else {
   
            // This not being started from an existing activity, and not part of a new task...
            // just put it in the top task, though these days this case should never happen.
            setTaskToCurrentTopOrCreateNewTask();
        }
        ... ...
        if (mDoResume) {
   
            final ActivityRecord topTaskActivity =
                    mStartActivity.getTask().topRunningActivityLocked();
            if (
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值