深入AMS源码(二)—— ActivityManagerService对Activity的调度管理

本文深入分析了AMS对Activity调度的源码实现,包括启动流程、复用活动、新对象创建及进程未启动时的处理。通过startActivity(),AMS执行一系列操作,如创建ActivityStarter,查询匹配的ResolveInfo,获取ActivityInfo,最终启动Activity。在启动过程中,涉及Activity的暂停、恢复,以及进程管理。对于复用活动,AMS会检查是否可以复用现有ActivityRecord,否则将创建新的Activity实例。
摘要由CSDN通过智能技术生成

1、概述

在上一篇深入AMS源码(一)——ActivityManagerService的基础知识文章介绍了AMS的基础信息,主要包括AMS中主要的数据结构、主要功能类和属性以及AMS中对生命周期的调度方式,本篇主要从源码的角度分析下AMS对Activity的调度逻辑,这也是AMS的主要功能;

2、源码分析

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 = mActivityStartController.checkTargetUser(userId, validateIncomingUser,
            Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
    return mActivityStartController.obtainStarter(intent, "startActivityAsUser”)  // 创建ActivityStarter对象
            .setCaller(caller) // 设置回调的Application对象
            .setCallingPackage(callingPackage) // 设置发起请求的包名
            .setResolvedType(resolvedType)
            .setResultTo(resultTo) // 设置setResult返回数据的Record对象,即调用startActivityForResult()的活动
            .setResultWho(resultWho) 
            .setRequestCode(requestCode) // 设置请求码
            .setStartFlags(startFlags)
            .setProfilerInfo(profilerInfo)
            .setActivityOptions(bOptions)
            .setMayWait(userId) // 所属用户ID
            .execute(); // 执行execute()
}

最终在startActivityAsUser()方法中,执行mActivityStartController.obtainStarter()创建ActivityStarter对象并初始化数据,调用execute()程序进入ActivityStarter类中

int execute() {
   
    try {
   
        if (mRequest.mayWait) {
     //首次进入执行mayWait()
            return startActivityMayWait(mRequest.caller, mRequest.callingUid,
                  …….
            mRequest.allowPendingRemoteAnimationRegistryLookup);
        } else {
   
            return startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent,
                  …….
            mRequest.allowPendingRemoteAnimationRegistryLookup);
        }
    } 
}

在设置userId是已经将mayWait设置为true了,所以execute()中会执行startActivityMayWait()方法

 final int startActivityMayWait(){
   
boolean componentSpecified = intent.getComponent() != null; // 1、
 
final int realCallingPid = Binder.getCallingPid(); // 获取当前进程的Uid
final int realCallingUid = Binder.getCallingUid();
final Intent ephemeralIntent = new Intent(intent); // 创建备份的Intent
intent = new Intent(intent); // 创建新的intent

 //(2)
ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,
        0 /* matchFlags */,computeResolveFilterUid(callingUid, realCallingUid, mRequest.filterCallingUid));
        
//(3)
ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);
final ActivityRecord[] outRecord = new ActivityRecord[1];
int res = startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo, 
        voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid,
        callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options,
        ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason,
        allowPendingRemoteAnimationRegistryLookup);

在startActivityMayWait()中主要执行四个操作

  1. 判断当前Intent中是否含有数据,并创建新的Intent对象封装数据
  2. 校验PMS中扫描到的mActivities集合中能处理Intent的ResolveInfo,查询不到则失败;
  3. 查找启动的目标活动对应的ActivityInfo
  4. 调用startActivity()执行Activity启动
  • mSupervisor.resolveIntent()
mService.getPackageManagerInternalLocked().resolveIntent( 
        intent, resolvedType, modifiedFlags, userId, true, filterCallingUid);
PackageManagerInternal getPackageManagerInternalLocked() {
   
    if (mPackageManagerInt == null) {
   
        mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class); // 获取PackageManagerInternalImpl()
    }
    return mPackageManagerInt;
}

在PMS启动完成后,会使用LocalService注册PackageManagerInternalImpl()对象,它是PMS的内部类;

LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl());

通过LocalServices对象调用的实际是PackageManagerInternalImpl.resolveIntent()中的方法,resolveIntent()中又调用resolveIntentInternal()方法

private ResolveInfo resolveIntentInternal(Intent intent, String resolvedType,
        int flags, int userId, boolean resolveForStart, int filterCallingUid) {
   
    try {
   
        if (!sUserManager.exists(userId)) return null; // 1、检查程序的userId
        final int callingUid = Binder.getCallingUid();
        flags = updateFlagsForResolve(flags, userId, intent, filterCallingUid, resolveForStart);//2、更新Flag
        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
                false /*requireFullPermission*/, false /*checkShell*/, "resolve intent");
       //3、从PMS遍历后保存的Intent-filter结合中查询能处理Intent的ResolveInfo的集合
        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType,
                flags, filterCallingUid, userId, resolveForStart, true /*allowDynamicSplits*/); 
      
        final ResolveInfo bestChoice =
                chooseBestActivity(intent, resolvedType, flags, query, userId);//4、匹配最好的ResolveInfo
        return bestChoice; // 返回ResolveInfo
    } 
}

在resolveIntentInternal()中回调用queryIntentActivitiesInternal()查询匹配的集合,这里实际是通过PMS中完成的,PMS中会遍历保存的四大组件信息的集合匹配能处理的信息对象,具体匹配细节见另一篇问文章深入PMS源码(三)—— PMS中intent-filter的匹配架构,在匹配成功后返回一个符合条件的集合,然后调用chooseBestActivity选择并返回最合适的ResolveInfo对象,之后继续执行下面的resolveActivity()

  • mSupervisor.resolveActivity()
ActivityInfo resolveActivity(Intent intent, ResolveInfo rInfo, int startFlags,
        ProfilerInfo profilerInfo) {
   
    final ActivityInfo aInfo = rInfo != null ? rInfo.activityInfo : null; // 1、获取其中的ActivityInfo对象
    if (aInfo != null) {
   
        intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));//2、设置Component对象
        final String intentLaunchToken = intent.getLaunchToken();
        if (aInfo.launchToken == null && intentLaunchToken != null) {
   
            aInfo.launchToken = intentLaunchToken;
        }
    }
    return aInfo; // 返回aInfo对象
}

resolveActivity()中逻辑很简单,根据查询获取到的ResolveInfo获取其中的ActivityInfo对象,并将信息封装在Component对象中,最后赋值给Intent对象,此时Component中就包含着要启动的真正对象;

  • startActivity()
ProcessRecord callerApp =  mService.getRecordForAppLocked(caller); // 1、

ActivityRecord sourceRecord = null; // 保存请求启动的父Activity
ActivityRecord resultRecord = null; // 保存结果返回的resultCode
if (resultTo != null) {
    // 处理resultTo回传数据
    sourceRecord = mSupervisor.isInAnyStackLocked(resultTo); //  2、
    if (sourceRecord != null) {
   
        if (requestCode >= 0 && !sourceRecord.finishing) {
   
            resultRecord = sourceRecord; // 默认赋值resultRecord为启动者所在的栈
        }
    }
}
 int launchFlags = intent.getFlags(); // 3、
 //Intent.FLAG_ACTIVITY_FORWARD_RESULT:处理跨Activity回传结果问题,这里主要针对在第一个Activity启动但需要在第三个activity返回数据
if ((launchFlags & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) {
   
 ……….
}
//初始化ActivityStack,默认使用resultRecord中TaskStack所属的管理类
final ActivityStack resultStack = resultRecord == null ? null : resultRecord.getStack();
boolean abort = !mSupervisor.checkStartAnyActivityPermission
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值