Android系统揭秘(一)-Activity启动流程,Android并发原理解析

// Note we want to go through this call for compatibility with

// applications that may have overridden the method.

startActivityForResult(intent, -1);

}

}

@Override

public void startActivityForResult(

String who, Intent intent, int requestCode, @Nullable Bundle options) {

Instrumentation.ActivityResult ar =

mInstrumentation.execStartActivity(

this, mMainThread.getApplicationThread(), mToken, who,

intent, requestCode, options);

}

然后调用了Instrumentation的execStartActivity方法

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

public ActivityResult execStartActivity(

Context who, IBinder contextThread, IBinder token, Activity target,

Intent intent, int requestCode, Bundle options) {

IApplicationThread whoThread = (IApplicationThread) contextThread;

try {

int result = ActivityManager.getService()

.startActivity(whoThread, who.getBasePackageName(), intent,

intent.resolveTypeIfNeeded(who.getContentResolver()),

token, target != null ? target.mEmbeddedID : null,

requestCode, 0, null, options);

checkStartActivityResult(result, intent);

} catch (RemoteException e) {

throw new RuntimeException(“Failure from system”, e);

}

return null;

}

首先调用ActivityManager的getService方法来获取AMS的代理对象,接着调用它的startActivity方法

这里需要注意的是,Android8.0之前是通过ActivityManagerNative的getDefault未获取AMS的代理对象的, 现在这个逻辑封装到了ActivityManager中而不是ActivityManagerNative中。

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

@SystemService(Context.ACTIVITY_SERVICE)

public class ActivityManager {

public static IActivityManager getService() {

return IActivityManagerSingleton.get();

}

private static final Singleton IActivityManagerSingleton =

new Singleton() {

@Override

protected IActivityManager create() {

// Context.ACTIVITY_SERVICE值为"activity"

final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);

final IActivityManager am = IActivityManager.Stub.asInterface(b);

return am;

}

};

}

getService方法调用了IActivityManagerSingleton的get方法,IActivityManagerSingleton是一个Singleton类。

这段代码采用的是AIDL,IActivityManager.java类是由AIDL工具在编译时自动生成的, 要实现进程间通信,服务器端也就是AMS只需要继承IActivityManager.Stub类并实现相应的方法就可以了。

注意Android8.0之前并没有采用AIDL,而是采用了类似AIDL的形式, 用AMS的代理对象ActivityManagerProxy来与AMS进行进程间通信, Android8.0去除了ActivityManagerNative的内部类ActivityManagerProxy, 代替它的是IActivityManager,它是AMS在本地的代理。 回到Instrumentation类的execStartActivity方法中, 从上面得知execStartActivity方法最终调用的是AMS的startActivity方法。

AMS到ApplicationThread的调用过程


我们先看看AMS里面的代码

frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

@Override

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());

}

@Override

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) {

// 判断调用者进程是否被隔离,如果被隔离则抛出SecurityException异常

enforceNotIsolatedCaller(“startActivity”);

// 检查调用者是否有权限,如果没有权限也会抛出SecurityException异常

userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),

userId, false, ALLOW_FULL_ONLY, “startActivity”, null);

// TODO: Switch to user app stacks here.

return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,

resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,

profilerInfo, null, null, bOptions, false, userId, null, “startActivityAsUser”);

}

可知,AMS使用ActivityStarter来启动Activity

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

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) {

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);

return res;

}

}

我们看下startActivityLocked方法,这个方法在ActivityStarter.startActivity前调用,会做一些校验

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) {

// 不会直接调用startActivity,要先做一些校验

if (TextUtils.isEmpty(reason)) {

throw new IllegalArgumentException(“Need to specify a 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);

if (outActivity != null) {

// mLastStartActivityRecord[0] is set in the call to startActivity above.

outActivity[0] = mLastStartActivityRecord[0];

}

// Aborted results are treated as successes externally, but we must track them internally.

return mLastStartActivityResult != START_ABORTED ? mLastStartActivityResult : START_SUCCESS;

}

接着调用startActivity方法

/** DO NOT call this method directly. Use {@link #startActivityLocked} instead. */

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) {

int err = ActivityManager.START_SUCCESS;

// Pull the optional Ephemeral Installer-only bundle out of the options early.

final Bundle verificationBundle

= options != null ? options.popAppVerificationBundle() : null;

ProcessRecord callerApp = null;

if (caller != null) {

// 得到的是代表Launcher进程的callerApp对象,它是ProcessRecord类型的,ProcessRecord用于描述一个应用程序进程

callerApp = mService.getRecordForAppLocked(caller);

if (callerApp != null) {

callingPid = callerApp.pid;

callingUid = callerApp.info.uid;

} else {

Slog.w(TAG, "Unable to find app for caller " + caller

  • " (pid=" + callingPid + ") when starting: "

  • intent.toString());

err = ActivityManager.START_PERMISSION_DENIED;

}

}

ActivityRecord r = new startActivity(mService, callerApp, callingPid, callingUid,

callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),

resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,

mSupervisor, options, sourceRecord);

if (outActivity != null) {

outActivity[0] = r;

}

doPendingActivityLaunchesLocked(false);

return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true,

options, inTask, outActivity);

}

在启动Activity之前,系统会创建一个startActivity对象,ActivityRecord用于描述一个Activity,用来记录一个Activity的所有信息

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);

} finally {

}

return result;

}

startActivityUnchecked方法代码比较多,主要处理与栈管理相关的逻辑。

// Note: This method should only be called from {@link startActivity}.

private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,

IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,

int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,

ActivityRecord[] outActivity) {

// If the activity being launched is the same as the one currently at the top, then

// we need to check if it should only be launched once.

final ActivityStack topStack = mSupervisor.mFocusedStack;

final ActivityRecord topFocused = topStack.topActivity();

final ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(mNotTop);

// 启动根Activity时会将Intent的Flag设置为FLAG_ACTIVITY_NEW_TASK

// Should this be considered a new task?

int result = START_SUCCESS;

if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask

&& (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {

newTask = true;

// setTaskFromReuseOrCreateNewTask方法内部会创建一个新的Activity任务栈

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 (result != START_SUCCESS) {

return result;

}

if (mDoResume) {

final ActivityRecord topTaskActivity =

mStartActivity.getTask().topRunningActivityLocked();

if (!mTargetStack.isFocusable()

|| (topTaskActivity != null && topTaskActivity.mTaskOverlay

&& mStartActivity != topTaskActivity)) {

} else {

// If the target stack was not previously focusable (previous top running activity

// on that stack was not visible) then any prior calls to move the stack to the

// will not update the focused stack. If starting the new activity now allows the

// task stack to be focusable, then ensure that we now update the focused stack

// accordingly.

if (mTargetStack.isFocusable() && !mSupervisor.isFocusedStack(mTargetStack)) {

mTargetStack.moveToFront(“startActivityUnchecked”);

}

mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,

mOptions);

}

} else {

mTargetStack.addRecentActivityLocked(mStartActivity);

}

mSupervisor.updateUserStackLocked(mStartActivity.userId, mTargetStack);

mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.getTask(), preferredLaunchStackId,

preferredLaunchDisplayId, mTargetStack.mStackId);

return START_SUCCESS;

}

接下来调用的是ActivityStackSupervisor的resumeFocusedStackTopActivityLocked方法,从这里开始要处理堆栈的事务了

frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java

boolean resumeFocusedStackTopActivityLocked(

ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {

if (!readyToResume()) {

return false;

}

if (targetStack != null && isFocusedStack(targetStack)) {

return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);

}

//获取要启动的Activity所在校的核顶的不是处于停止状态的ActivityRecord

final ActivityRecord r = mFocusedStack.topRunningActivityLocked();

if (r == null || r.state != RESUMED) {

mFocusedStack.resumeTopActivityUncheckedLocked(null, null);

} else if (r.state == RESUMED) {

// Kick off any lingering app transitions form the MoveTaskToFront operation.

mFocusedStack.executeAppTransition(targetOptions);

}

return false;

}

ActivityStackSupervisor相当于ActivityStack的帮助类,需要ActivityStack进行下一步堆栈的处理

frameworks/base/services/core/java/com/android/server/am/ActivityStack.java

boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {

if (mStackSupervisor.inResumeTopActivity) {

// Don’t even start recursing.

return false;

}

boolean result = false;

try {

// Protect against recursion.

mStackSupervisor.inResumeTopActivity = true;

result = resumeTopActivityInnerLocked(prev, options);

} finally {

mStackSupervisor.inResumeTopActivity = false;

}

final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);

if (next == null || !next.canTurnScreenOn()) {

checkReadyForSleep();

}

return result;

}

resumeTopActivityInnerLocked的内容很多,我们只关心以下代码

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {

mStackSupervisor.startSpecificActivityLocked(next, true, false);

return true;

}

又回到了ActivityStackSupervisor,调用startSpecificActivityLocked方法

frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java

void startSpecificActivityLocked(ActivityRecord r,

boolean andResume, boolean checkConfig) {

// Is this activity’s application already running?

ProcessRecord app = mService.getProcessRecordLocked(r.processName,

r.info.applicationInfo.uid, true);

r.getStack().setLaunchTime®;

if (app != null && app.thread != null) {

try {

if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0

|| !“android”.equals(r.info.packageName)) {

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
img

尾声

评论里面有些同学有疑问关于如何学习material design控件,我的建议是去GitHub搜,有很多同行给的例子,这些栗子足够入门。

有朋友说要是动真格的话,需要NDK以及JVM等的知识,首现**NDK并不是神秘的东西,**你跟着官方的步骤走一遍就知道什么回事了,无非就是一些代码格式以及原生/JAVA内存交互,进阶一点的有原生/JAVA线程交互,线程交互确实有点蛋疼,但平常避免用就好了,再说对于初学者来说关心NDK干嘛,据鄙人以前的经历,只在音视频通信和一个嵌入式信号处理(离线)的两个项目中用过,嵌入式信号处理是JAVA->NDK->.SO->MATLAB这样调用的我原来MATLAB的代码,其他的大多就用在游戏上了吧,一般的互联网公司会有人给你公司的SO包的。
至于JVM,该掌握的那部分,相信我,你会掌握的,不该你掌握的,有那些专门研究JVM的人来做,不如省省心有空看看计算机系统,编译原理。

一句话,平常多写多练,这是最基本的程序员的素质,尽量挤时间,读理论基础书籍,JVM不是未来30年唯一的虚拟机,JAVA也不一定再风靡未来30年工业界,其他的系统和语言也会雨后春笋冒出来,但你理论扎实会让你很快理解学会一个语言或者框架,你平常写的多会让你很快熟练的将新学的东西应用到实际中。
初学者,一句话,多练。

片转存中…(img-fNafYgAS-1711048989760)]
[外链图片转存中…(img-cfSO5bUj-1711048989760)]

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
[外链图片转存中…(img-gDFpSzZL-1711048989761)]

尾声

评论里面有些同学有疑问关于如何学习material design控件,我的建议是去GitHub搜,有很多同行给的例子,这些栗子足够入门。

有朋友说要是动真格的话,需要NDK以及JVM等的知识,首现**NDK并不是神秘的东西,**你跟着官方的步骤走一遍就知道什么回事了,无非就是一些代码格式以及原生/JAVA内存交互,进阶一点的有原生/JAVA线程交互,线程交互确实有点蛋疼,但平常避免用就好了,再说对于初学者来说关心NDK干嘛,据鄙人以前的经历,只在音视频通信和一个嵌入式信号处理(离线)的两个项目中用过,嵌入式信号处理是JAVA->NDK->.SO->MATLAB这样调用的我原来MATLAB的代码,其他的大多就用在游戏上了吧,一般的互联网公司会有人给你公司的SO包的。
至于JVM,该掌握的那部分,相信我,你会掌握的,不该你掌握的,有那些专门研究JVM的人来做,不如省省心有空看看计算机系统,编译原理。

一句话,平常多写多练,这是最基本的程序员的素质,尽量挤时间,读理论基础书籍,JVM不是未来30年唯一的虚拟机,JAVA也不一定再风靡未来30年工业界,其他的系统和语言也会雨后春笋冒出来,但你理论扎实会让你很快理解学会一个语言或者框架,你平常写的多会让你很快熟练的将新学的东西应用到实际中。
初学者,一句话,多练。

由于文章篇幅问题复制链接查看详细文章以及获取学习笔记链接:前往我的GitHub

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值