Android 面试总结 - Activity的启动流程

文章详细解析了Android中startActivityForResult方法的执行过程,重点在于Instrumentation的execStartActivity调用,涉及进程间通信,从App进程到ActivityTaskManagerService,再到ActivityStack的执行逻辑,展示了Android启动Activity的底层工作机制。
摘要由CSDN通过智能技术生成

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode) {

startActivityForResult(intent, requestCode, null);

}

调用 startActivityForResult 的重载方法

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,

@Nullable Bundle options) {

if (mParent == null) {

options = transferSpringboardActivityOptions(options);

// 关键来了

Instrumentation.ActivityResult ar =

mInstrumentation.execStartActivity(

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

intent, requestCode, options);

if (ar != null) {

mMainThread.sendActivityResult(

mToken, mEmbeddedID, requestCode, ar.getResultCode(),

ar.getResultData());

}

if (requestCode >= 0) {

// If this start is requesting a result, we can avoid making

// the activity visible until the result is received. Setting

// this code during onCreate(Bundle savedInstanceState) or onResume() will keep the

// activity hidden during this time, to avoid flickering.

// This can only be done when a result is requested because

// that guarantees we will get information back when the

// activity is finished, no matter what happens to it.

mStartedActivity = true;

}

cancelInputsAndStartExitTransition(options);

// TODO Consider clearing/flushing other event sources and events for child windows.

} else {

if (options != null) {

mParent.startActivityFromChild(this, intent, requestCode, options);

} else {

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

// existing applications that may have overridden it.

mParent.startActivityFromChild(this, intent, requestCode);

}

}

}

关键调用 mInstrumentation.execStartActivity

app 进程到 ATMS 进程

Instrumentation#execStartActivity

@UnsupportedAppUsage

public ActivityResult execStartActivity(

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

Intent intent, int requestCode, Bundle options) {

IApplicationThread whoThread = (IApplicationThread) contextThread;

Uri referrer = target != null ? target.onProvideReferrer() : null;

if (referrer != null) {

intent.putExtra(Intent.EXTRA_REFERRER, referrer);

}

if (mActivityMonitors != null) {

synchronized (mSync) {

final int N = mActivityMonitors.size();

for (int i=0; i<N; i++) {

final ActivityMonitor am = mActivityMonitors.get(i);

ActivityResult result = null;

if (am.ignoreMatchingSpecificIntents()) {

result = am.onStartActivity(intent);

}

if (result != null) {

am.mHits++;

return result;

} else if (am.match(who, null, intent)) {

am.mHits++;

if (am.isBlocking()) {

return requestCode >= 0 ? am.getResult() : null;

}

break;

}

}

}

}

try {

intent.migrateExtraStreamToClipData(who);

intent.prepareToLeaveProcess(who);

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

checkStartActivityResult(result, intent);

} catch (RemoteException e) {

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

}

return null;

}

最终通过 ActivityTaskManager.getService() 获取ATMS的服务代理并调用 ATMS.startActivity 方法,这时从 app 的进程进入到 SystemServer 进程,发生了一次跨进程!

ATMS 到 ActivityThread

ActivityTaskManagerService#startActivity

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

}

ActivityTaskManagerService#startActivityAsUser

@Override

public int startActivityAsUser(IApplicationThread caller, String callingPackage,

String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo,

String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo,

Bundle bOptions, int userId) {

return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,

resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,

true /validateIncomingUser/);

}

ActivityTaskManagerService#startActivityAsUser

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

// TODO: Switch to user app stacks here.

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

}

最后 return 的对象设置了那么多属性并在最后调用 excute() 执行。

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

先看看 getActivityStartController() 是个啥

ActivityStartController getActivityStartController() {

return mActivityStartController;

}

getActivityStartController().obtainStarter(intent, “startActivityAsUser”)

ActivityStarter obtainStarter(Intent intent, String reason) {

return mFactory.obtain().setIntent(intent).setReason(reason);

}

mFactory.obtain() 使用工厂模式从 DefaultFactory 类的缓存池(最大缓存数量为3) 中取出 ActivityStarter 对象

getActivityStartController().obtainStarter(intent, “startActivityAsUser”)

.setCaller(caller)

setCaller(caller) caller 是 IApplicationThread 类型的对象,等于 ActivityStarter 里缓存了与 app 进程连接的桥梁,之后可以进行跨进程调用 app 进程。

ApplicationThread是ActivityThread内部类,继承自IApplicationThread.Stub,作为服务端接受AMS发出的请求并执行,ApplicationThread是ActivityThread与AMS连接的桥梁。

再看最后的 execute()

return getActivityStartController().obtainStarter(intent, “startActivityAsUser”)

.setCaller(caller)

.execute();

ActivityStarter#execute

int execute() {

try {

res = executeRequest(mRequest);

return getExternalResult(mRequest.waitResult == null ? res
waitForResult(res, mLastStartActivityRecord));

} finally {

onExecutionComplete();

}

}

ActivityStarter#executeRequest

/**

*执行活动启动请求,开始启动活动的旅程。在这里

*首先执行几个初步检查。正常的活动启动流程将

*通过{@link#startActivityUnchecked}到{@link#startactivitynner}。

*/

private int executeRequest(Request request) {

// 在这里创建 ActivityRecord 对象,用于描述 Activity 信息

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

callingPackage, callingFeatureId, intent, resolvedType, aInfo,

mService.getGlobalConfiguration(), resultRecord, resultWho, requestCode,

request.componentSpecified, voiceSession != null, mSupervisor, checkedOptions,

sourceRecord);

mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,

request.voiceInteractor, startFlags, true /* doResume */, checkedOptions, inTask,

restrictedBgActivity, intentGrants);

return mLastStartActivityResult;

}

ActivityStarter#startActivityUnchecked

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

Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, “startActivityInner”);

// 关键

result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,

startFlags, doResume, options, inTask, restrictedBgActivity, intentGrants);

} finally {

Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);

startedActivityStack = handleStartResult(r, result);

mService.continueWindowLayout();

}

postStartActivityProcessing(r, result, startedActivityStack);

return result;

}

ActivityStarter#startActivityInner

int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,

IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,

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

boolean restrictedBgActivity, NeededUriGrants intentGrants) {

mRootWindowContainer.resumeFocusedStacksTopActivities(

mTargetStack, mStartActivity, mOptions);

return START_SUCCESS;

}

调用了RootWindowContainer#resumeFocusedStacksTopActivities

boolean resumeFocusedStacksTopActivities(

ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {

result |= focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions);

return result;

}

调用 ActivityStack#resumeTopActivityUncheckedLocked

boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {

result = resumeTopActivityInnerLocked(prev, options);

return result;

}

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {

//关键关键!!! 传入了 next.app.getThread() 返回的是 IApplication

final ClientTransaction transaction =

ClientTransaction.obtain(next.app.getThread(), next.appToken);

transaction.setLifecycleStateRequest(

ResumeActivityItem.obtain(next.app.getReportedProcState(),

dc.isNextTransitionForward()));

mAtmService.getLifecycleManager().scheduleTransaction(transaction);

return true;

}

mStackSupervisor.startSpecificActivity(next, true, true);

ActivityStackSupervisor#startSpecificActivity

void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) {

realStartActivityLocked(r, wpc, andResume, checkConfig);

}

ActivityStackSupervisor#realStartActivityLocked

boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,

boolean andResume, boolean checkConfig) throws RemoteException {

// Create activity launch transaction.

// 关键关键!!! 传入了 proc.getThread() 返回的是 IApplication

// 赋值给 ClientTransaction 的 mClient 对象

final ClientTransaction clientTransaction = ClientTransaction.obtain(

proc.getThread(), r.appToken);

final DisplayContent dc = r.getDisplay().mDisplayContent;

clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),

System.identityHashCode®, r.info,

// TODO: Have this take the merged configuration instead of separate global

// and override configs.

mergedConfiguration.getGlobalConfiguration(),

mergedConfiguration.getOverrideConfiguration(), r.compat,

r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),

r.getSavedState(), r.getPersistentSavedState(), results, newIntents,

dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),

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

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

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

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

最后

答应大伙的备战金三银四,大厂面试真题来啦!

这份资料我从春招开始,就会将各博客、论坛。网站上等优质的Android开发中高级面试题收集起来,然后全网寻找最优的解答方案。每一道面试题都是百分百的大厂面经真题+最优解答。包知识脉络 + 诸多细节。
节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。
给文章留个小赞,就可以免费领取啦~

戳我领取:3000页Android开发者架构师核心知识笔记

《960全网最全Android开发笔记》

《379页Android开发面试宝典》

包含了腾讯、百度、小米、阿里、乐视、美团、58、猎豹、360、新浪、搜狐等一线互联网公司面试被问到的题目。熟悉本文中列出的知识点会大大增加通过前两轮技术面试的几率。

如何使用它?
1.可以通过目录索引直接翻看需要的知识点,查漏补缺。
2.五角星数表示面试问到的频率,代表重要推荐指数

《507页Android开发相关源码解析》

只要是程序员,不管是Java还是Android,如果不去阅读源码,只看API文档,那就只是停留于皮毛,这对我们知识体系的建立和完备以及实战技术的提升都是不利的。

真正最能锻炼能力的便是直接去阅读源码,不仅限于阅读各大系统源码,还包括各种优秀的开源库。

腾讯、字节跳动、阿里、百度等BAT大厂 2020-2021面试真题解析

资料收集不易,如果大家喜欢这篇文章,或者对你有帮助不妨多多点赞转发关注哦。文章会持续更新的。绝对干货!!!

学习,也可以分享给身边好友一起学习。
给文章留个小赞,就可以免费领取啦~

戳我领取:3000页Android开发者架构师核心知识笔记

《960全网最全Android开发笔记》

[外链图片转存中…(img-zBDPmtdm-1710504669494)]

《379页Android开发面试宝典》

包含了腾讯、百度、小米、阿里、乐视、美团、58、猎豹、360、新浪、搜狐等一线互联网公司面试被问到的题目。熟悉本文中列出的知识点会大大增加通过前两轮技术面试的几率。

如何使用它?
1.可以通过目录索引直接翻看需要的知识点,查漏补缺。
2.五角星数表示面试问到的频率,代表重要推荐指数

[外链图片转存中…(img-76bv6zGW-1710504669495)]

《507页Android开发相关源码解析》

只要是程序员,不管是Java还是Android,如果不去阅读源码,只看API文档,那就只是停留于皮毛,这对我们知识体系的建立和完备以及实战技术的提升都是不利的。

真正最能锻炼能力的便是直接去阅读源码,不仅限于阅读各大系统源码,还包括各种优秀的开源库。

[外链图片转存中…(img-FuhvDx6Z-1710504669495)]

腾讯、字节跳动、阿里、百度等BAT大厂 2020-2021面试真题解析

[外链图片转存中…(img-x7CZfVVE-1710504669496)]

资料收集不易,如果大家喜欢这篇文章,或者对你有帮助不妨多多点赞转发关注哦。文章会持续更新的。绝对干货!!!

  • 26
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值