目录
  1. 1. Activity工作原理
    1. 1.1. APP启动原理
重拾Android-【吃透源码系列】之Activity

Activity工作原理

APP启动原理

在手机屏幕上点击某个APP的图标,比如淘宝APP,此时,整个手机屏幕就是一个“巨型APP”,而这个Activity所在的APP,也就是Launcher。也因此Launcher和我们点击的淘宝APP是属两个不同的APP,它们位于不同的进程中,其双方的通信是通过 Binder 完成的,此时AMS就是担负两者通信的桥梁。以启动淘宝APP为例,分析整体启动流程:

  • 1) Launcher 通知 AMS

  • 2) AMS 通知 Launcher

  • 3) Launcher进入Paused状态

  • 4) AMS 检查淘宝APP启动与否

  • 5) 淘宝APP启动后通知 AMS

  • 6) AMS通知淘宝APP启动页面

  • Launcher进程请求AMS进程启动Activity

Launcher启动后会将已安装的应用程序的快捷图标显示到桌面上,这些应用程序的快捷图标就是启动根Activity的入口,当点击应用程序的快捷图标时,就会调用Launcher的startActivitySafely方法,继而经由 Activity —> Instrumentation —> IActivityManager —> AMS(实现了IActivityManager.Stub就可以进行跨进程通信)【Android 11.0源码新增ActivityTaskManagerService】

在 Instrumentation#execStartActivity 中

// 通过AIDL跨进程通信,进入AMS
int result = ActivityTaskManager.getService().startActivity(whoThread,
who.getBasePackageName(), who.getAttributionTag(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()), token,
target != null ? target.mEmbeddedID : null, requestCode, 0, null, options);

在 ATMS 中

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

// ... 方法传递

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) {
assertPackageMatchesCallingUid(callingPackage);
enforceNotIsolatedCaller("startActivityAsUser");

userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");

// 使用构建者模式,替代以往方法传参贼多参数形式,并且引入 ActivityStartController,进而通过工厂模式 获取 ActivityStarter
// ActivityStarter:【这是加载Activity的控制类,会收集所有的逻辑来决定如何将Intent和Flags转换为Activity,并将Activity、Task以及Stack相关联】
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();

}

在 ActivityStarter#execute 中

int execute() {
// 步骤1 resolveActivity --> 收集所有的Intent信息以及Flags确定Activity、Task以及Stack关系

// 步骤2 执行请求 --> 获取Launcher进程
res = executeRequest(mRequest);

// 返回结果:是否有被中止(这里源码考虑到电话来访等特殊场景)
return getExternalResult(mRequest.waitResult == null ? res
: waitForResult(res, mLastStartActivityRecord));
}

private int executeRequest(Request request) {
// ...省略

// 获得最终启动Activity的结果:里面主要是处理 startFlags,task相关工作
mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
request.voiceInteractor, startFlags, true /* doResume */, checkedOptions, inTask,
restrictedBgActivity, intentGrants);

// ...省略
return mLastStartActivityResult;
}

// 该方法主要处理与栈管理相关的逻辑
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, Task inTask,
boolean restrictedBgActivity, NeededUriGrants intentGrants) {
int result = START_CANCELED;
final ActivityStack startedActivityStack;
try {
mService.deferWindowLayout();
result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, doResume, options, inTask, restrictedBgActivity, intentGrants);
} finally {
startedActivityStack = handleStartResult(r, result);
mService.continueWindowLayout();
}

postStartActivityProcessing(r, result, startedActivityStack);

return result;
}

// 启动一个活动,并确定该活动是否应该添加到现有任务栈的顶部 或者 向现有活动传递一个新的Intent。
// 同时操作Activity任务栈返回请求的或有效的堆栈/显示。
int startActivityInner() {

// 计算启动任务栈的flags
computeLaunchingTaskFlags();
// 计算L原进程的任务栈
computeSourceStack();
// 设置启动Activity的Intent的Flag
mIntent.setFlags(mLaunchFlags);

final ActivityRecord targetTaskTop = newTask
? null : targetTask.getTopNonFinishingActivity();

// ... 省略
}
  • AMS进程到ApplicationThread的调用
  • ActivityThread启动Activity


打赏
  • 微信
  • 支付宝

评论