2024年安卓最新Android系统揭秘(一)-Activity启动流程(上),安卓开发面试题Java

文末

对于很多初中级Android工程师而言,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长且无助。 整理的这些架构技术希望对Android开发的朋友们有所参考以及少走弯路,本文的重点是你有没有收获与成长,其余的都不重要,希望读者们能谨记这一点。

最后想要拿高薪实现技术提升薪水得到质的飞跃。最快捷的方式,就是有人可以带着你一起分析,这样学习起来最为高效,所以为了大家能够顺利进阶中高级、架构师,我特地为大家准备了一套高手学习的源码和框架视频等精品Android架构师教程,保证你学了以后保证薪资上升一个台阶。

当你有了学习线路,学习哪些内容,也知道以后的路怎么走了,理论看多了总要实践的。

进阶学习视频

附上:我们之前因为秋招收集的二十套一二线互联网公司Android面试真题 (含BAT、小米、华为、美团、滴滴)和我自己整理Android复习笔记(包含Android基础知识点、Android扩展知识点、Android源码解析、设计模式汇总、Gradle知识点、常见算法题汇总。)

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

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

// Don’t add this if it is a platform component that is marked

// to run in multiple processes, because this is actually

// part of the framework so doesn’t make sense to track as a

// separate apk in the process.

app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,

mService.mProcessStats);

}

realStartActivityLocked(r, app, andResume, checkConfig);

return;

} catch (RemoteException e) {

Slog.w(TAG, "Exception when starting activity "

  • r.intent.getComponent().flattenToShortString(), e);

}

// If a dead object exception was thrown – fall through to

// restart the application.

}

// 启动应用程序进程

mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,

“activity”, r.intent.getComponent(), false, false, true);

}

接下来就是realStartActivityLocked,到这里堆栈基本处理完毕,准备通知ApplicationThread

final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,

boolean andResume, boolean checkConfig) throws RemoteException {

app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,

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, app.repProcState, r.icicle,

r.persistentState, results, newIntents, !andResume,

mService.isNextTransitionForward(), profilerInfo);

}

这里的app.thread指的是IApplicationThread,它的实现是ActivityThread的内部类ApplicationThread, 其中ApplicationThread继承了IApplicationThread.Stub

ActivityThread 启动Activity 的过程


上一节写到AMS通过各种途径,最终通知到ApplicationThread。而在这一步骤,ApplicationThread通过消息机制告知ActivityThread,

frameworks/base/core/java/android/app/ActivityThread.java#ApplicationThread

@Override

public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,

ActivityInfo info, Configuration curConfig, Configuration overrideConfig,

CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,

int procState, Bundle state, PersistableBundle persistentState,

List pendingResults, List pendingNewIntents,

boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {

updateProcessState(procState, false);

ActivityClientRecord r = new ActivityClientRecord();

r.token = token;

r.ident = ident;

r.intent = intent;

r.referrer = referrer;

r.voiceInteractor = voiceInteractor;

r.activityInfo = info;

r.compatInfo = compatInfo;

r.state = state;

r.persistentState = persistentState;

r.pendingResults = pendingResults;

r.pendingIntents = pendingNewIntents;

r.startsNotResumed = notResumed;

r.isForward = isForward;

r.profilerInfo = profilerInfo;

r.overrideConfig = overrideConfig;

updatePendingConfiguration(curConfig);

sendMessage(H.LAUNCH_ACTIVITY, r);

}

我们看看sendMessage的代码

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

private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {

if (DEBUG_MESSAGES) Slog.v(

TAG, "SCHEDULE " + what + " " + mH.codeToString(what)

  • ": " + arg1 + " / " + obj);

Message msg = Message.obtain();

msg.what = what;

msg.obj = obj;

msg.arg1 = arg1;

msg.arg2 = arg2;

if (async) {

msg.setAsynchronous(true);

}

mH.sendMessage(msg);

}

它向一个mH对象发送的一个what为H.LAUNCH_ACTIVITY(值为100),obj为ActivityClientRecord的Message,H是ActivityThread内的一个Handler

H收到指令后会调用handleLaunchActivity方法

private class H extends Handler {

public static final int LAUNCH_ACTIVITY = 100;

public static final int RELAUNCH_ACTIVITY = 101;

String codeToString(int code) {

if (DEBUG_MESSAGES) {

switch (code) {

case LAUNCH_ACTIVITY: return “LAUNCH_ACTIVITY”;

}

}

return Integer.toString(code);

}

public void handleMessage(Message msg) {

if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));

switch (msg.what) {

case LAUNCH_ACTIVITY: {

Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, “activityStart”);

final ActivityClientRecord r = (ActivityClientRecord) msg.obj;

r.packageInfo = getPackageInfoNoCheck(

r.activityInfo.applicationInfo, r.compatInfo);

handleLaunchActivity(r, null, “LAUNCH_ACTIVITY”);

Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

} break;

case RELAUNCH_ACTIVITY: {

Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, “activityRestart”);

ActivityClientRecord r = (ActivityClientRecord)msg.obj;

handleRelaunchActivity®;

Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

} break;

}

Object obj = msg.obj;

if (obj instanceof SomeArgs) {

((SomeArgs) obj).recycle();

}

if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + codeToString(msg.what));

}

}

这里我们先看下getPackageInfoNoCheck方法,这个方法主要用于获取应用的包信息,然后返回LoadedApk对象

public final LoadedApk getPackageInfoNoCheck(ApplicationInfo ai,

CompatibilityInfo compatInfo) {

return getPackageInfo(ai, compatInfo, null, false, true, false);

}

private LoadedApk getPackageInfo(ApplicationInfo aInfo, CompatibilityInfo compatInfo,

ClassLoader baseLoader, boolean securityViolation, boolean includeCode,

boolean registerPackage) {

final boolean differentUser = (UserHandle.myUserId() != UserHandle.getUserId(aInfo.uid));

synchronized (mResourcesManager) {

WeakReference ref;

if (differentUser) {

// Caching not supported across users

ref = null;

} else if (includeCode) {

ref = mPackages.get(aInfo.packageName);

} else {

ref = mResourcePackages.get(aInfo.packageName);

}

LoadedApk packageInfo = ref != null ? ref.get() : null;

if (packageInfo == null || (packageInfo.mResources != null

&& !packageInfo.mResources.getAssets().isUpToDate())) {

if (localLOGV) Slog.v(TAG, (includeCode ? "Loading code package "
"Loading resource-only package ") + aInfo.packageName
  • " (in " + (mBoundApplication != null

? mBoundApplication.processName : null)

  • “)”);

packageInfo =

new LoadedApk(this, aInfo, compatInfo, baseLoader,

securityViolation, includeCode &&

(aInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0, registerPackage);

if (mSystemThread && “android”.equals(aInfo.packageName)) {

packageInfo.installSystemApplicationInfo(aInfo,

getSystemContext().mPackageInfo.getClassLoader());

}

if (differentUser) {

// Caching not supported across users

} else if (includeCode) {

mPackages.put(aInfo.packageName,

new WeakReference(packageInfo));

} else {

mResourcePackages.put(aInfo.packageName,

new WeakReference(packageInfo));

}

}

return packageInfo;

}

}

然后接着看handleLaunchActivity方法

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {

WindowManagerGlobal.initialize();

Activity a = performLaunchActivity(r, customIntent);

if (a != null) {

r.createdConfig = new Configuration(mConfiguration);

reportSizeConfigurations®;

Bundle oldState = r.state;

// resume

handleResumeActivity(r.token, false, r.isForward,

!r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);

if (!r.activity.mFinished && r.startsNotResumed) {

if (r.isPreHoneycomb()) {

r.state = oldState;

}

}

最后

由于题目很多整理答案的工作量太大,所以仅限于提供知识点,详细的很多问题和参考答案我都整理成了 PDF文件

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {

WindowManagerGlobal.initialize();

Activity a = performLaunchActivity(r, customIntent);

if (a != null) {

r.createdConfig = new Configuration(mConfiguration);

reportSizeConfigurations®;

Bundle oldState = r.state;

// resume

handleResumeActivity(r.token, false, r.isForward,

!r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);

if (!r.activity.mFinished && r.startsNotResumed) {

if (r.isPreHoneycomb()) {

r.state = oldState;

}

}

最后

由于题目很多整理答案的工作量太大,所以仅限于提供知识点,详细的很多问题和参考答案我都整理成了 PDF文件

[外链图片转存中…(img-lZU8faX2-1715015823259)]

[外链图片转存中…(img-XPVJgdsP-1715015823260)]

[外链图片转存中…(img-BFUyfXJt-1715015823260)]

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值