概述
源代码版本:android-28(Android 9.0)
我们的手机桌面(就是按Home
键回到的地方),其实也是一个Android应用程序,即 Launcher。所以不管是点击桌面应用图标,还是我们在应用内启动新Activity,最终都是从同一个地方开始的,那就是Activity类。
由于Activity启动流程还是相对复杂,分析时省略了相当部分的其他代码,我们抱着先摸清调用流程主干路径的目的,进行扼要的摘录。这样也可以先有个整体的印象,便于理解。
Activity启动完整的调用流程如下(可能需要放大查看):
如果再省略一些细节,粗略的流程如下:
AMS: ActivityManagerService
下面来看详细流程。
Activity->AMS
Activity.java:
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode, @Nullable Bundle options) {
if (mParent == null) {
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken,
this, intent, requestCode, options);
// 省略部分代码
}
}
Activity中,最终执行的是Instrumentation.execStartActivity。
Instrumentation.java:
// android.app.Instrumentation.java
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
// 省略部分代码
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中的静态方法,我们看一看ActivityManager里的相关代码。
ActivityManager.java:
public class ActivityManager {
// 省略部分代码
/**
* @hide
*/
public static IActivityManager getService() {
return IActivityManagerSingleton.get();
}
private static final Singleton<IActivityManager> IActivityManagerSingleton =
new Singleton<IActivityManager>() {
@Override
protected IActivityManager create() {
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
final IActivityManager am = IActivityManager.Stub.asInterface(b);
return am;
}
};
// 省略部分代码
}
通过以上代码可以看到,Instrumentation调用ActivityManager的静态方法,获取了IActivityManager ,最终是通过Binder IPC机制来实现对IActivityManager方法的调用。IActivityManager在Android源代码中的位置:frameworks/base/core/java/android/app/IActivityManager.aidl。
Singleton是Android系统提供的一个懒加载模式单例辅助类:
package android.util;
/**
* Singleton helper class for lazily initialization.
*
* Modeled after frameworks/base/include/utils/Singleton.h
*
* @hide
*/
public abstract class Singleton<T> {
private T mInstance;
protected abstract T create();
public final T get() {
synchronized (this) {
if (mInstance == null) {
mInstance = create();
}
return mInstance;
}
}
}
AMS->ActivityThread
ASS: ActivityStackSupervisor
CLM: ClientLifecycleManager
ActivityManagerService.java:
查看代码可以发现,ActivityManagerService是实现了IActivityManager接口的,那么Instrumentation最终调用的就是ActivityManagerService的startActivity了.
public class ActivityManagerService extends IActivityManager.Stub
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
// 省略部分代码
@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) {
return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
true /*validateIncomingUser*/);
}
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) {
enforceNotIsolatedCaller("startActivity");
userId = mActivityStartController.checkTargetUser(userId, validateIncomingUser,
Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
// TODO: Switch to user app stacks here.
return mActivityStartController.obtainStarter(intent, "startActivityAsUser")
.setCaller(caller)
.setCallingPackage(callingPackage)
.setResolvedType(resolvedType)
.setResultTo(resultTo)
.setResultWho(resultWho)
.setRequestCode(requestCode)
.setStartFlags(startFlags)
.setProfilerInfo(profilerInfo)
.setActivityOptions(bOptions)
.setMayWait(userId) // 该方法内部会将 mRequest.mayWait 设为true
.execute();
}
// 省略部分代码
}
mActivityStartController.obtainStarter获取的是一个ActivityStarter类的实例,并调用了它的execute
方法。
ActivityStarter.java:
class ActivityStarter {
// 省略部分代码
/**
* Starts an activity based on the request parameters provided earlier.
* @return The starter result.
*/
int execute() {
try {
// 因为前面调用的 setMayWait(userId) 方法会将 mRequest.mayWait 设为true,
// 所以这里会进入if分支
if (mRequest.mayWait) {
return startActivityMayWait(mRequest.caller, mRequest.callingUid,
mRequest.callingPackage, mRequest.intent, mRequest.resolvedType,
mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
mRequest.resultWho, mRequest.requestCode, mRequest.startFlags,
mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,
mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId,
mRequest.inTask, mRequest.reason,
mRequest.allowPendingRemoteAnimationRegistryLookup);
}
// 省略部分代码
} finally {
onExecutionComplete();
}
}
// 省略部分代码
private 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, SafeActivityOptions options, boolean ignoreTargetSecurity,
int userId, TaskRecord inTask, String reason,
boolean allowPendingRemoteAnimationRegistryLookup) {
// 省略部分代码
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);
// 省略部分代码
return res;
}
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,
SafeActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
ActivityRecord[] outActivity, TaskRecord inTask, String reason,
boolean allowPendingRemoteAnimationRegistryLookup) {
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, allowPendingRemoteAnimationRegistryLookup);
if (outActivity != null) {
// mLastStartActivityRecord[0] is set in the call to startActivity above.
outActivity[0] = mLastStartActivityRecord[0];
}
return getExternalResult(mLastStartActivityResult);
}
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,
SafeActivityOptions options,
boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
TaskRecord inTask, boolean allowPendingRemoteAnimationRegistryLookup) {
// 省略部分代码
return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
true /* doResume */, checkedOptions, inTask, outActivity);
}
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 {
// If we are not able to proceed, disassociate the activity from the task. Leaving an
// activity in an incomplete state can lead to issues, such as performing operations
// without a window container.
final ActivityStack stack = mStartActivity.getStack();
if (!ActivityManager.isStartResultSuccessful(result) && stack != null) {
stack.finishActivityLocked(mStartActivity, RESULT_CANCELED,
null /* intentResultData */, "startActivity", true /* oomAdj */);
}
mService.mWindowManager.continueSurfaceLayout();
}
postStartActivityProcessing(r, result, mTargetStack);
return result;
}
// 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 (mDoResume) {
final ActivityRecord topTaskActivity =
mStartActivity.getTask().topRunningActivityLocked();
if (!mTargetStack.isFocusable()
|| (topTaskActivity != null && topTaskActivity.mTaskOverlay
&& mStartActivity != topTaskActivity)) {
// 省略部分代码
} else {
if (mTargetStack.isFocusable() && !mSupervisor.isFocusedStack(mTargetStack)) {
mTargetStack.moveToFront("startActivityUnchecked");
}
mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
mOptions);
}
// 省略部分代码
return START_SUCCESS;
}
}
在 ActivityStarter 类的 execute 方法中,调用了 startActivityMayWait 方法,里面又层层递进地调用了几个重载的 startActivity 方法,并最终调用到了 startActivityUnchecked 方法,startActivityUnchecked 中调用了 ActivityStackSupervisor 的 resumeFocusedStackTopActivityLocked 方法。
ActivityStackSupervisor.java:
boolean resumeFocusedStackTopActivityLocked(
ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
// 省略部分代码
if (targetStack != null && isFocusedStack(targetStack)) {
return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}
// 省略部分代码
return false;
}
ActivityStack .java:
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
// 省略部分代码
boolean result = false;
try {
// 省略部分代码
result = resumeTopActivityInnerLocked(prev, options);
final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
if (next == null || !next.canTurnScreenOn()) {
checkReadyForSleep();
}
} finally {
mStackSupervisor.inResumeTopActivity = false;
}
return result;
}
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
if (next.app != null && next.app.thread != null) {
// 省略部分代码
} else {
// 省略部分代码
mStackSupervisor.startSpecificActivityLocked(next, true, true);
}
return true;
}
ActivityStackSupervisor.java:
void startSpecificActivityLocked(ActivityRecord r,
boolean andResume, boolean checkConfig) {
// 省略部分代码
if (app != null && app.thread != null) {
try {
// 省略部分代码
realStartActivityLocked(r, app, andResume, checkConfig);
return;
} catch (RemoteException e) {
}
}
mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
"activity", r.intent.getComponent(), false, false, true);
}
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
boolean andResume, boolean checkConfig) throws RemoteException {
// 省略部分代码
try {
// 省略部分代码
try {
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
} catch (RemoteException e) {
// 省略部分代码
}
}
// 省略部分代码
}
ClientLifecycleManager.java:
void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
final IApplicationThread client = transaction.getClient();
transaction.schedule();
if (!(client instanceof Binder)) {
transaction.recycle();
}
}
ClientTransaction.java:
/** Target client. */
private IApplicationThread mClient;
public void schedule() throws RemoteException {
mClient.scheduleTransaction(this);
}
IApplicationThread在源码中的路径:frameworks/base/core/java/android/app/IApplicationThread.aidl
接下来的流程,是通过Binder IPC,调用到 IApplicationThread 的实现类。在 ActivityThread 中,有一个内部类: ApplicationThread,这个类实现了 IApplicationThread 接口。所以接下来的流程又回到了 ActivityThread 中。
ActivityThread->Activity
ApplicationThread的实现类
public final class ActivityThread extends ClientTransactionHandler {
// 省略部分代码
private class ApplicationThread extends IApplicationThread.Stub {
// 省略部分代码
@Override
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
ActivityThread.this.scheduleTransaction(transaction);
}
}
// 省略部分代码
}
可以看到,在 ApplicationThread 的 scheduleTransaction 方法中,调用的是 ActivityThread 的 scheduleTransaction 方法,但是如果我们尝试在 ActivityThread 中搜索 scheduleTransaction 方法,会发现根本找不到。这是因为,scheduleTransaction 是 ActivityThread 的父类 ClientTransactionHandler 提供的方法,而且 ActivityThread 并没有进行重载实现。所以我们需要看一下 ClientTransactionHandler 里面的实现。
ClientTransactionHandler.java:
void scheduleTransaction(ClientTransaction transaction) {
transaction.preExecute(this);
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
可以看到,最终是调用了 sendMessage,而 sendMessage 方法,ActivityThread 是重写了实现的。
public final class ActivityThread extends ClientTransactionHandler {
final H mH = new H();
// 省略部分代码
void sendMessage(int what, Object obj) {
sendMessage(what, obj, 0, 0, false);
}
private void sendMessage(int what, Object obj, int arg1) {
sendMessage(what, obj, arg1, 0, false);
}
private void sendMessage(int what, Object obj, int arg1, int arg2) {
sendMessage(what, obj, arg1, arg2, false);
}
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);
}
// 省略部分代码
class H extends Handler {
// 省略部分代码
public void handleMessage(Message msg) {
switch (msg.what) {
// 省略部分代码
case EXECUTE_TRANSACTION:
final ClientTransaction transaction = (ClientTransaction) msg.obj;
mTransactionExecutor.execute(transaction);
if (isSystem()) {
transaction.recycle();
}
break;
}
// 省略部分代码
}
}
}
到这里我们就可以看到,启动 Activity 的消息,最终是通过 Handler 进入了应用的主线程消息队列,并由 Handler 的实现类 H 进行具体处理。
这里有个问题需要注意: 既然回调到 ApplicationThread,都已经回到 ActivityThread 了, 为什么还要经过Handler去绕一圈呢?
这是因为:ApplicationThread 虽然是 ActivityThread 的内部类,但回调到 ApplicationThread 的 scheduleTransaction 的方法时,当前还是在一个 Binder 线程中的,而生命周期等一系列方法回调都是在主线程上的,所以这里自然需要先将从 Binder IPC 回来、但还在 Binder线程中的消息投放到应用主线程的消息队列,才能进行后续处理。
我们可以通过在 ApplicationThread 的 scheduleTransaction 的方法和 H 类 handleMessage 的 EXECUTE_TRANSACTION 这个case 分支中设置一个断点,来查看上面描述的情况:
最后
以上就是缓慢大叔为你收集整理的Activity启动流程分析的全部内容,希望文章能够帮你解决Activity启动流程分析所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复