大家好,我是考100分的小小码 ,祝大家学习进步,加薪顺利呀。今天说一说Activity的启动过程详解(基于Android10.0)「建议收藏」,希望您对编程的造诣更进一步.
一、概述
话说Android中有四大组件:Activity、Service、BroadcastReceiver、ContentProvider。我们最常接触也是用户直接感受到的就是Activity了,今天来就说说Android启动的执行过程和工作原理。
Activity是一种 展示型组件,用于展示给用户一个可以交互的页面。Activity是Android中最重要的组件,对用户来说,所有的Activity就是一个App的全部,而其他组件用户是不能直接感知的。在开发层面,要启动一个Activity可以使用Intent,分显式和隐式,并且还可以设置Activity的启动模式。
Android系统对四大组件都做了很大程度的封装,这样我们可以快速使用组件。Activity的启动在系统封装后,变的极为简单,显示启动activity代码如下:
Intent intent = new Intent(this, TestActivity.class);
this.startActivity(intent);
这样就可以启动TestActivity了,那么问题来了,
- 这个代码是如何启动一个Activity的?
- 里面做了哪些事情?
- onCreate这些生命周期是何时执行的?
- Activity对象何时创建的?
- 视图是怎么处理以及何时可见的?
- 根activity(第一个activity)又是如何启动的?
那么为啥需要了解这些问题呢?不了解 ,平时开发好像也没啥问题啊。其实不然,解决这些问题后,你会对Android系统有更深层次的理解,也会学习到系统源码优秀的设计。并且对解决一些高级问题和深入的性能优化问题有很大帮助,是技术进阶的必要阶段。这就需要我们通过阅读源码来梳理这些问题,但另一方面,系统源码是很庞大繁杂的,我们需要带着问题抓住主流程,不能陷入代码细节——这是阅读系统源码以及其他第三方库源码的正确姿势。
这里先给出 Activity启动 的 整体交互图:
其中创建应用进程的逻辑一般在启动
根activity时会走到,普通activity不涉及Launcher和Zygote。
下面开始详细的流程分析,最后会给出完整的交互关系图。
二、流程分析
2.1 Activity启动的发起
下面我们就来对Activity的工作流程进行梳理,达到对Activity整体流程的掌握。从startActivity方法开始,会走到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) {
mStartedActivity = true;
}
cancelInputsAndStartExitTransition(options);
} else {
...
}
}
看到里面调用了mInstrumentation.execStartActivity方法,其中一个参数mMainThread.getApplicationThread(),它的类型是ApplicationThread,ApplicationThread是ActivityThread的内部类,继承IApplicationThread.Stub,也是个Binder对象,在Activity工作流程中有重要作用。而Instrumentation具有跟踪application及activity生命周期的功能,用于android 应用测试框架中代码检测。接着看下mInstrumentation.execStartActivity方法:
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);
}
...
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess(who);
int result = ActivityTaskManager.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;
}
这里看到Activity的启动又交给了ActivityTaskManager.getService(),这是啥?跟进去看看:
//ActivityTaskManager
public static IActivityTaskManager getService() {
return IActivityTaskManagerSingleton.get();
}
private static final Singleton<IActivityTaskManager> IActivityTaskManagerSingleton =
new Singleton<IActivityTaskManager>() {
@Override
protected IActivityTaskManager create() {
final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE);
return IActivityTaskManager.Stub.asInterface(b);
}
};
看到IBinder这个标志,这里你应该明白了:这里是获取一个跨进程的服务。获取的什么服务呢?是ActivityTaskManagerService(ATMS),它继承于IActivityTaskManager.Stub,是个Binder对象,并且是通过单例提供服务的。 ATMS是用于管理Activity及其容器(任务、堆栈、显示等)的系统服务,运行在系统服务进程(system_server)之中。
值得说明的是,ATMS是在Android10中新增的,分担了之前ActivityManagerService(AMS)的一部分功能(activity task相关)。 在Android10 之前 ,这个地方获取的是服务是AMS。查看Android10的AMS,你会发现startActivity方法内也是调用了ATMS的startActivity方法。所以在理解上,ATMS就隶属于AMS。
接着看,ActivityTaskManager.getService().startActivity有个返回值result,且调用了checkStartActivityResult(result, intent):
public static void checkStartActivityResult(int res, Object intent) {
if (!ActivityManager.isStartResultFatalError(res)) {
return;
}
switch (res) {
case ActivityManager.START_INTENT_NOT_RESOLVED:
case ActivityManager.START_CLASS_NOT_FOUND:
if (intent instanceof Intent && ((Intent)intent).getComponent() != null)
throw new ActivityNotFoundException(
"Unable to find explicit activity class "
+ ((Intent)intent).getComponent().toShortString()
+ "; have you declared this activity in your AndroidManifest.xml?");
throw new ActivityNotFoundException(
"No Activity found to handle " + intent);
case ActivityManager.START_PERMISSION_DENIED:
throw new SecurityException("Not allowed to start activity "
+ intent);
...
case ActivityManager.START_CANCELED:
throw new AndroidRuntimeException("Activity could not be started for "
+ intent);
default:
throw new AndroidRuntimeException("Unknown error code "
+ res + " when starting " + intent);
}
}
这是用来检查Activity启动的结果,如果发生致命错误,就会抛出对应的异常。看到第一个case中就抛出了 have you declared this activity in your AndroidManifest.xml?——如果Activity没在Manifest中注册就会有这个错误。
2.2 Activity的管理——ATMS
好了,到这里,Activity的启动就跨进程(IPC)的转移到系统进程提供的服务ATMS中了,接着看ATMS的startActivity:
//ActivityTaskManagerService
@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 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*/);
}
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("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)
.setResolvedType(resolvedType)
.setResultTo(resultTo)
.setResultWho(resultWho)
.setRequestCode(requestCode)
.setStartFlags(startFlags)
.setProfilerInfo(profilerInfo)
.setActivityOptions(bOptions)
.setMayWait(userId)
.execute();
}
跟到startActivityAsUser中,通过getActivityStartController().obtainStarter方法获取ActivityStarter实例 然后调用一系列方法,最后的execute()方法是开始启动activity:
int execute() {
try {
// TODO(b/64750076): Look into passing request directly to these methods to allow
// for transactional diffs and preprocessing.
if (mRequest.mayWait) {
return startActivityMayWait(mRequest.caller, mRequest.callingUid,
mRequest.callingPackage, mRequest.realCallingPid, mRequest.realCallingUid,
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,
mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart);
} else {
return startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent,
mRequest.resolvedType, mRequest.activityInfo, mRequest.resolveInfo,
mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
mRequest.resultWho, mRequest.requestCode, mRequest.callingPid,
mRequest.callingUid, mRequest.callingPackage, mRequest.realCallingPid,
mRequest.realCallingUid, mRequest.startFlags, mRequest.activityOptions,
mRequest.ignoreTargetSecurity, mRequest.componentSpecified,
mRequest.outActivity, mRequest.inTask, mRequest.reason,
mRequest.allowPendingRemoteAnimationRegistryLookup,
mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart);
}
} finally {
onExecutionComplete();
}
}
分了两种情况,不过 不论startActivityMayWait还是startActivity最终都是走到下面这个startActivity方法:
private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
ActivityRecord[] outActivity, boolean restrictedBgActivity) {
int result = START_CANCELED;
final ActivityStack startedActivityStack;
try {
mService.mWindowManager.deferSurfaceLayout();
result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, doResume, options, inTask, outActivity, restrictedBgActivity);
} finally {
final ActivityStack currentStack = r.getActivityStack();
startedActivityStack = currentStack != null ? currentStack : mTargetStack;
...
}
postStartActivityProcessing(r, result, startedActivityStack);
return result;
}
里面有调用了startActivityUnchecked方法,之后调用RootActivityContainer的resumeFocusedStacksTopActivities方法。RootActivityContainer是Android10新增的类,分担了之前ActivityStackSupervisor的部分功能。接着跳转到ActivityStack的resumeTopActivityUncheckedLocked方法:
//ActivityStack
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
if (mInResumeTopActivity) {
// Don't even start recursing.
return false;
}
boolean result = false;
try {
mInResumeTopActivity = true;
result = resumeTopActivityInnerLocked(prev, options);
final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
if (next == null || !next.canTurnScreenOn()) {
checkReadyForSleep();
}
} finally {
mInResumeTopActivity = false;
}
return result;
}
跟进resumeTopActivityInnerLocked方法:
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
...
boolean pausing = getDisplay().pauseBackStacks(userLeaving, next, false);
if (mResumedActivity != null) {
if (DEBUG_STATES) Slog.d(TAG_STATES,
"resumeTopActivityLocked: Pausing " + mResumedActivity);
// 暂停上一个Activity
pausing |= startPausingLocked(userLeaving, false, next, false);
}
...
//这里next.attachedToProcess(),只有启动了的Activity才会返回true
if (next.attachedToProcess()) {
...
try {
final ClientTransaction transaction =
ClientTransaction.obtain(next.app.getThread(), next.appToken);
...
//启动了的Activity就发送ResumeActivityItem事务给客户端了,后面会讲到
transaction.setLifecycleStateRequest(
ResumeActivityItem.obtain(next.app.getReportedProcState(),
getDisplay().mDisplayContent.isNextTransitionForward()));
mService.getLifecycleManager().scheduleTransaction(transaction);
....
} catch (Exception e) {
....
mStackSupervisor.startSpecificActivityLocked(next, true, false);
return true;
}
....
} else {
....
if (SHOW_APP_STARTING_PREVIEW) {
//这里就是 冷启动时 出现白屏 的原因了:取根activity的主题背景 展示StartingWindow
next.showStartingWindow(null , false ,false);
}
// 继续当前Activity,普通activity的正常启动 关注这里即可
mStackSupervisor.startSpecificActivityLocked(next, true, true);
}
return true;
}
先对上一个Activity执行pause操作,再执行当前创建操作,代码最终进入到了ActivityStackSupervisor.startSpecificActivityLocked方法中。这里有个点注意下,启动activity前调用了next.showStartingWindow方法来展示一个window,这就是 冷启动时 出现白屏 的原因了。我们继续看ActivityStackSupervisor.startSpecificActivityLocked方法:
void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
// Is this activity's application already running?
final WindowProcessController wpc =
mService.getProcessController(r.processName, r.info.applicationInfo.uid);
boolean knownToBeDead = false;
if (wpc != null && wpc.hasThread()) {
try {
realStartActivityLocked(r, wpc, andResume, checkConfig);
return;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting activity "
+ r.intent.getComponent().flattenToShortString(), e);
}
knownToBeDead = true;
}
...
try {
if (Trace.isTagEnabled(TRACE_TAG_ACTIVITY_MANAGER)) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "dispatchingStartProcess:"
+ r.processName);
}
// 上面的wpc != null && wpc.hasThread()不满足的话,说明没有进程,就会取创建进程
final Message msg = PooledLambda.obtainMessage(
ActivityManagerInternal::startProcess, mService.mAmInternal, r.processName,
r.info.applicationInfo, knownToBeDead, "activity", r.intent.getComponent());
mService.mH.sendMessage(msg);
} finally {
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
}
有个判断条件if (wpc != null && wpc.hasThread()),意思是是否启动了应用进程,内部是通过IApplicationThread是否为空来判断。这里我们只看已启动应用进程的情况,及调用了realStartActivityLocked方法,,:
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
boolean andResume, boolean checkConfig) throws RemoteException {
...
// Create activity launch transaction.
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), 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.icicle, r.persistentState, results, newIntents,
dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
r.assistToken));
// Set desired final state.
final ActivityLifecycleItem lifecycleItem;
if (andResume) {
lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
} else {
lifecycleItem = PauseActivityItem.obtain();
}
clientTransaction.setLifecycleStateRequest(lifecycleItem);
// Schedule transaction.
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
...
return true;
}
中间有段代码如上,通过 ClientTransaction.obtain( proc.getThread(), r.appToken)获取了clientTransaction,其中参数proc.getThread()是IApplicationThread,就是前面提到的ApplicationThread在系统进程的代理。
ClientTransaction是包含一系列的待客户端处理的事务的容器,客户端接收后取出事务并执行。
接着看,使用clientTransaction.addCallback添加了LaunchActivityItem实例:
//都是用来发送到客户端的
private List<ClientTransactionItem> mActivityCallbacks;
public void addCallback(ClientTransactionItem activityCallback) {
if (mActivityCallbacks == null) {
mActivityCallbacks = new ArrayList<>();
}
mActivityCallbacks.add(activityCallback);
}
看下LaunchActivityItem实例的获取:
/** Obtain an instance initialized with provided params. */
public static LaunchActivityItem obtain(Intent intent, int ident, ActivityInfo info, Configuration curConfig, Configuration overrideConfig, CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor, int procState, Bundle state, PersistableBundle persistentState, List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents, boolean isForward, ProfilerInfo profilerInfo, IBinder assistToken) {
LaunchActivityItem instance = ObjectPool.obtain(LaunchActivityItem.class);
if (instance == null) {
instance = new LaunchActivityItem();
}
setValues(instance, intent, ident, info, curConfig, overrideConfig, compatInfo, referrer,
voiceInteractor, procState, state, persistentState, pendingResults,
pendingNewIntents, isForward, profilerInfo, assistToken);
return instance;
}
new了一个LaunchActivityItem然后设置各种值。我们从名字就能看出,它就是用来启动activity的。它是怎么发挥作用的呢?接着看:
回到realStartActivityLocked方法,接着调用了mService.getLifecycleManager().scheduleTransaction(clientTransaction),mService是ActivityTaskManagerService,getLifecycleManager()方法获取的是ClientLifecycleManager实例,它的scheduleTransaction方法如下:
void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
final IApplicationThread client = transaction.getClient();
transaction.schedule();
if (!(client instanceof Binder)) {
transaction.recycle();
}
}
就是调用ClientTransaction的schedule方法,那就看看:
public void schedule() throws RemoteException {
mClient.scheduleTransaction(this);
}
很简单,就是调用IApplicationThread的scheduleTransaction方法。由于IApplicationThread是ApplicationThread在系统进程的代理,所以真正执行的地方就是 客户端的ApplicationThread中了。也就是说,Activity启动的操作又跨进程的还给了客户端。
好了,到这里我们稍稍梳理下:启动Activity的操作从客户端 跨进程 转移到 ATMS,ATMS通过ActivityStarter、ActivityStack、ActivityStackSupervisor 对 Activity任务、activity栈、Activity记录 管理后,又用过跨进程把正在启动过程又转移到了客户端。
2.3 线程切换及消息处理——mH
接着上面的分析,我们找到ApplicationThread的scheduleTransaction方法:
@Override
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
ActivityThread.this.scheduleTransaction(transaction);
}
那就再看ActivityThread的scheduleTransaction方法,实际在其父类ClientTransactionHandler中:
void scheduleTransaction(ClientTransaction transaction) {
transaction.preExecute(this);
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
使用sendMessage发送消息,参数是ActivityThread.H.EXECUTE_TRANSACTION和transaction,接着看:
void sendMessage(int what, Object obj) {
sendMessage(what, obj, 0, 0, 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);
}
最后调用了mH.sendMessage(msg),mH是个啥?我们看看:
//ActivityThread
final H mH = new H();
class H extends Handler {
public static final int BIND_APPLICATION = 110;
@UnsupportedAppUsage
public static final int EXIT_APPLICATION = 111;
@UnsupportedAppUsage
public static final int RECEIVER = 113;
@UnsupportedAppUsage
public static final int CREATE_SERVICE = 114;
@UnsupportedAppUsage
public static final int SERVICE_ARGS = 115;
...
public static final int EXECUTE_TRANSACTION = 159;
public static final int RELAUNCH_ACTIVITY = 160;
...
public void handleMessage(Message msg) {
if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
switch (msg.what) {
case BIND_APPLICATION:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
AppBindData data = (AppBindData)msg.obj;
handleBindApplication(data);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
case EXIT_APPLICATION:
if (mInitialApplication != null) {
mInitialApplication.onTerminate();
}
Looper.myLooper().quit();
break;
case RECEIVER:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveComp");
handleReceiver((ReceiverData)msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
case CREATE_SERVICE:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceCreate: " + String.valueOf(msg.obj)));
handleCreateService((CreateServiceData)msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
case BIND_SERVICE:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind");
handleBindService((BindServiceData)msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
...
case EXECUTE_TRANSACTION:
final ClientTransaction transaction = (ClientTransaction) msg.obj;
mTransactionExecutor.execute(transaction);
if (isSystem()) {
// Client transactions inside system process are recycled on the client side
// instead of ClientLifecycleManager to avoid being cleared before this
// message is handled.
transaction.recycle();
}
break;
case RELAUNCH_ACTIVITY:
handleRelaunchActivityLocally((IBinder) msg.obj);
break;
...
}
Object obj = msg.obj;
if (obj instanceof SomeArgs) {
((SomeArgs) obj).recycle();
}
if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + codeToString(msg.what));
}
}
mH是在创建ActivityThread实例时赋值的,是自定义Handler子类H的实例,也就是在ActivityThread的main方法中,并且初始化是已经主线程已经有了mainLooper,所以,使用这个mH来sendMessage就把消息发送到了主线程。
那么是从哪个线程发送的呢?那就要看看ApplicationThread的scheduleTransaction方法是执行在哪个线程了。根据IPC知识,我们知道,服务器的Binder方法运行在Binder的线程池中,也就是说系统进行跨进程调用ApplicationThread的scheduleTransaction就是执行在Binder的线程池中的了。
到这里,消息就在主线程处理了,那么是怎么处理Activity的启动的呢?接着看。我们找到ActivityThread.H.EXECUTE_TRANSACTION这个消息的处理,就在handleMessage方法的倒数第三个case(就在上面代码):取出ClientTransaction实例,调用TransactionExecutor的execute方法,那就看看:
public void execute(ClientTransaction transaction) {
if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Start resolving transaction");
final IBinder token = transaction.getActivityToken();
...
executeCallbacks(transaction);
executeLifecycleState(transaction);
...
}
继续跟进executeCallbacks方法:
public void executeCallbacks(ClientTransaction transaction) {
final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
if (callbacks == null || callbacks.isEmpty()) {
// No callbacks to execute, return early.
return;
}
if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Resolving callbacks in transaction");
final IBinder token = transaction.getActivityToken();
ActivityClientRecord r = mTransactionHandler.getActivityClient(token);
// In case when post-execution state of the last callback matches the final state requested
// for the activity in this transaction, we won't do the last transition here and do it when
// moving to final state instead (because it may contain additional parameters from server).
final ActivityLifecycleItem finalStateRequest = transaction.getLifecycleStateRequest();
final int finalState = finalStateRequest != null ? finalStateRequest.getTargetState()
: UNDEFINED;
// Index of the last callback that requests some post-execution state.
final int lastCallbackRequestingState = lastCallbackRequestingState(transaction);
final int size = callbacks.size();
for (int i = 0; i < size; ++i) {
final ClientTransactionItem item = callbacks.get(i);
...
item.execute(mTransactionHandler, token, mPendingActions);
item.postExecute(mTransactionHandler, token, mPendingActions);
...
}
}
遍历callbacks,调用ClientTransactionItem的execute方法,而我们这里要关注的是ClientTransactionItem的子类LaunchActivityItem,看下它的execute方法:
public void execute(ClientTransactionHandler client, IBinder token, PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
mPendingResults, mPendingNewIntents, mIsForward,
mProfilerInfo, client, mAssistToken);
client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
里面调用了client.handleLaunchActivity方法,client是ClientTransactionHandler的实例,是在TransactionExecutor构造方法传入的,TransactionExecutor创建是在ActivityThread中:
//ActivityThread
private final TransactionExecutor mTransactionExecutor = new TransactionExecutor(this);
所以,client.handleLaunchActivity方法就是ActivityThread的handleLaunchActivity方法。
好了,到这里 ApplicationThread把启动Activity的操作,通过mH切到了主线程,走到了ActivityThread的handleLaunchActivity方法。
2.4 Activity启动核心实现——初始化及生命周期
那就接着看:
public Activity handleLaunchActivity(ActivityClientRecord r, PendingTransactionActions pendingActions, Intent customIntent) {
...
final Activity a = performLaunchActivity(r, customIntent);
...
return a;
}
继续跟performLaunchActivity方法,这里就是activity 启动的核心实现了:
/** activity 启动的核心实现. */
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
//1、从ActivityClientRecord获取待启动的Activity的组件信息
ActivityInfo aInfo = r.activityInfo;
if (r.packageInfo == null) {
r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
Context.CONTEXT_INCLUDE_CODE);
}
ComponentName component = r.intent.getComponent();
if (component == null) {
component = r.intent.resolveActivity(
mInitialApplication.getPackageManager());
r.intent.setComponent(component);
}
if (r.activityInfo.targetActivity != null) {
component = new ComponentName(r.activityInfo.packageName,
r.activityInfo.targetActivity);
}
//创建ContextImpl对象
ContextImpl appContext = createBaseContextForActivity(r);
Activity activity = null;
try {
//2、创建activity实例
java.lang.ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
StrictMode.incrementExpectedActivityCount(activity.getClass());
r.intent.setExtrasClassLoader(cl);
r.intent.prepareToEnterProcess();
if (r.state != null) {
r.state.setClassLoader(cl);
}
} catch (Exception e) {
..
}
try {
//3、创建Application对象(如果没有的话)
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
...
if (activity != null) {
CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
Configuration config = new Configuration(mCompatConfiguration);
if (r.overrideConfig != null) {
config.updateFrom(r.overrideConfig);
}
Window window = null;
if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
window = r.mPendingRemoveWindow;
r.mPendingRemoveWindow = null;
r.mPendingRemoveWindowManager = null;
}
appContext.setOuterContext(activity);
//4、attach方法为activity关联上下文环境
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config,
r.referrer, r.voiceInteractor, window, r.configCallback,
r.assistToken);
if (customIntent != null) {
activity.mIntent = customIntent;
}
r.lastNonConfigurationInstances = null;
checkAndBlockForNetworkAccess();
activity.mStartedActivity = false;
int theme = r.activityInfo.getThemeResource();
if (theme != 0) {
activity.setTheme(theme);
}
activity.mCalled = false;
//5、调用生命周期onCreate
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
if (!activity.mCalled) {
throw new SuperNotCalledException(
"Activity " + r.intent.getComponent().toShortString() +
" did not call through to super.onCreate()");
}
r.activity = activity;
}
r.setState(ON_CREATE);
synchronized (mResourcesManager) {
mActivities.put(r.token, r);
}
}
...
return activity;
}
performLaunchActivity主要完成以下事情:
- 从ActivityClientRecord获取待启动的Activity的组件信息
- 通过mInstrumentation.newActivity方法使用类加载器创建activity实例
- 通过LoadedApk的makeApplication方法创建Application对象,内部也是通过mInstrumentation使用类加载器,创建后就调用了instrumentation.callApplicationOnCreate方法,也就是Application的onCreate方法。
- 创建ContextImpl对象并通过activity.attach方法对重要数据初始化,关联了Context的具体实现ContextImpl,attach方法内部还完成了window创建,这样Window接收到外部事件后就能传递给Activity了。
- 调用Activity的onCreate方法,是通过 mInstrumentation.callActivityOnCreate方法完成。
到这里Activity的onCreate方法执行完,那么onStart、onResume呢?
上面看到LaunchActivityItem,是用来启动Activity的,也就是走到Activity的onCreate,那么是不是有 “XXXActivityItem”呢? 有的:
- LaunchActivityItem 远程App端的onCreate生命周期事务
- ResumeActivityItem 远程App端的onResume生命周期事务
- PauseActivityItem 远程App端的onPause生命周期事务
- StopActivityItem 远程App端的onStop生命周期事务
- DestroyActivityItem 远程App端onDestroy生命周期事务
另外梳理过程中涉及的几个类:
- ClientTransaction 客户端事务控制者
- ClientLifecycleManager 客户端的生命周期事务控制者
- TransactionExecutor 远程通信事务执行者
那么我们再来看看ResumeActivityItem吧。
我们再来重新看看在ActivityStackSupervisor的realStartActivityLocked方法:
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
boolean andResume, boolean checkConfig) throws RemoteException {
...
// Create activity launch transaction.
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), r.info,
mergedConfiguration.getGlobalConfiguration(),
mergedConfiguration.getOverrideConfiguration(), r.compat,
r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
r.icicle, r.persistentState, results, newIntents,
dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
r.assistToken));
// Set desired final state.
final ActivityLifecycleItem lifecycleItem;
//这里ResumeActivityItem
if (andResume) {
lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
} else {
lifecycleItem = PauseActivityItem.obtain();
}
clientTransaction.setLifecycleStateRequest(lifecycleItem);
// Schedule transaction.
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
...
return true;
}
前面只说了通过clientTransaction.addCallback添加LaunchActivityItem实例,在注意下面接着调用了clientTransaction.setLifecycleStateRequest(lifecycleItem)方法,lifecycleItem是ResumeActivityItem或PauseActivityItem实例,这里我们关注ResumeActivityItem,先看下setLifecycleStateRequest方法:
/** * Final lifecycle state in which the client activity should be after the transaction is * executed. */
private ActivityLifecycleItem mLifecycleStateRequest;
public void setLifecycleStateRequest(ActivityLifecycleItem stateRequest) {
mLifecycleStateRequest = stateRequest;
}
mLifecycleStateRequest表示执行transaction后的最终的生命周期状态。
继续看处理ActivityThread.H.EXECUTE_TRANSACTION这个消息的处理,即TransactionExecutor的execute方法:
public void execute(ClientTransaction transaction) {
if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Start resolving transaction");
final IBinder token = transaction.getActivityToken();
...
executeCallbacks(transaction);
executeLifecycleState(transaction);
...
}
前面我们关注的是executeCallbacks方法,现在看看executeLifecycleState方法:
/** Transition to the final state if requested by the transaction. */
private void executeLifecycleState(ClientTransaction transaction) {
final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
if (lifecycleItem == null) {
// No lifecycle request, return early.
return;
}
final IBinder token = transaction.getActivityToken();
final ActivityClientRecord r = mTransactionHandler.getActivityClient(token);
...
// Execute the final transition with proper parameters.
lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
}
这里取出了ActivityLifecycleItem并且调用了它的execute方法,实际就是ResumeActivityItem的方法:
@Override
public void execute(ClientTransactionHandler client, IBinder token, PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityResume");
client.handleResumeActivity(token, true /* finalStateRequest */, mIsForward,
"RESUME_ACTIVITY");
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
经过上面分析实际是走到ActivityThread的handleResumeActivity方法:
@Override
public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,
String reason) {
...
// performResumeActivity内部会走onStart、onResume
final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);
if (r == null) {
// We didn't actually resume the activity, so skipping any follow-up actions.
return;
}
...
if (r.window == null && !a.mFinished && willBeVisible) {
r.window = r.activity.getWindow();
View decor = r.window.getDecorView();
decor.setVisibility(View.INVISIBLE);
ViewManager wm = a.getWindowManager();
WindowManager.LayoutParams l = r.window.getAttributes();
a.mDecor = decor;
l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
l.softInputMode |= forwardBit;
if (r.mPreserveWindow) {
a.mWindowAdded = true;
r.mPreserveWindow = false;
ViewRootImpl impl = decor.getViewRootImpl();
if (impl != null) {
impl.notifyChildRebuilt();
}
}
...
if (!r.activity.mFinished && willBeVisible && r.activity.mDecor != null && !r.hideForNow) {
if (r.newConfig != null) {
performConfigurationChangedForActivity(r, r.newConfig);
if (DEBUG_CONFIGURATION) {
Slog.v(TAG, "Resuming activity " + r.activityInfo.name + " with newConfig "
+ r.activity.mCurrentConfig);
}
r.newConfig = null;
}
if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward=" + isForward); WindowManager.LayoutParams l = r.window.getAttributes(); if ((l.softInputMode & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) != forwardBit) { l.softInputMode = (l.softInputMode & (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)) | forwardBit; if (r.activity.mVisibleFromClient) { ViewManager wm = a.getWindowManager(); View decor = r.window.getDecorView(); wm.updateViewLayout(decor, l); } } r.activity.mVisibleFromServer = true; mNumVisibleActivities++; if (r.activity.mVisibleFromClient) { //添加window、设置可见 r.activity.makeVisible(); } } r.nextIdle = mNewActivities; mNewActivities = r; if (localLOGV) Slog.v(TAG, "Scheduling idle handler for " + r); Looper.myQueue().addIdleHandler(new Idler()); }
handleResumeActivity主要做了以下事情:
- 调用生命周期:通过performResumeActivity方法,内部调用生命周期onStart、onResume方法
- 设置视图可见:通过activity.makeVisible方法,添加window、设置可见。(所以视图的真正可见是在onResume方法之后)
先来看第一点,生命周期的调用。即performResumeActivity方法:
public ActivityClientRecord performResumeActivity(IBinder token, boolean finalStateRequest, String reason) {
final ActivityClientRecord r = mActivities.get(token);
...
try {
...
r.activity.performResume(r.startsNotResumed, reason);
...
}
...
return r;
}
调用了activity.performResume方法:
final void performResume(boolean followedByPause, String reason) {
dispatchActivityPreResumed();
//内部会走onStart
performRestart(true /* start */, reason);
...
// 走onResume
mInstrumentation.callActivityOnResume(this);
...
//这里是走fragment的onResume
mFragments.dispatchResume();
mFragments.execPendingActions();
...
}
先调用了performRestart(),performRestart()又会调用performStart(),performStart()内部调用了mInstrumentation.callActivityOnStart(this),也就是**Activity的onStart()**方法了。
然后是mInstrumentation.callActivityOnResume,也就是**Activity的onResume()**方法了。到这里启动后的生命周期走完了。
再看第二点,设置视图可见。即activity.makeVisible()方法:
//Activity
void makeVisible() {
if (!mWindowAdded) {
ViewManager wm = getWindowManager();
wm.addView(mDecor, getWindow().getAttributes());
mWindowAdded = true;
}
mDecor.setVisibility(View.VISIBLE);
}
这里把activity的顶级布局mDecor通过windowManager.addView()方法,把视图添加到window,并设置mDecor可见。到这里视图是真正可见了。值得注意的是,视图的真正可见是在onResume方法之后的。
另外一点,Activity视图渲染到Window后,会设置window焦点变化,先走到DecorView的onWindowFocusChanged方法,最后是到Activity的onWindowFocusChanged方法,表示首帧绘制完成,此时Activity可交互。
好了,到这里就是真正创建完成并且可见了。
梳理成关系图如下:
涉及的类梳理如下:
类名 | 作用 |
---|---|
ActivityThread | 应用的入口类,系统通过调用main函数,开启消息循环队列。ActivityThread所在线程被称为应用的主线程(UI线程) |
ApplicationThread | 是ActivityThread的内部类,继承IApplicationThread.Stub,是一个IBinder,是ActiivtyThread和AMS通信的桥梁,AMS则通过代理调用此App进程的本地方法,运行在Binder线程池 |
H | 继承Handler,在ActivityThread中初始化,即主线程Handler,用于主线程所有消息的处理。本片中主要用于把消息从Binder线程池切换到主线程 |
Intrumentation | 具有跟踪application及activity生命周期的功能,用于监控app和系统的交互 |
ActivityManagerService | Android中最核心的服务之一,负责系统中四大组件的启动、切换、调度及应用进程的管理和调度等工作,其职责与操作系统中的进程管理和调度模块相类似,因此它在Android中非常重要,它本身也是一个Binder的实现类。 |
ActivityTaskManagerService | 管理activity及其容器(task, stacks, displays)的系统服务(Android10中新增,分担了AMS的部分职责) |
ActivityStarter | 用于解释如何启动活动。该类收集所有逻辑,用于确定Intent和flag应如何转换为活动以及相关的任务和堆栈 |
ActivityStack | 用来管理系统所有的Activity,内部维护了Activity的所有状态和Activity相关的列表等数据 |
ActivityStackSupervisor | 负责所有Activity栈的管理。AMS的stack管理主要有三个类,ActivityStackSupervisor,ActivityStack和TaskRecord |
ClientLifecycleManager | 客户端生命周期执行请求管理 |
ClientTransaction | 是包含一系列的 待客户端处理的事务 的容器,客户端接收后取出事务并执行 |
LaunchActivityItem、ResumeActivityItem | 继承ClientTransactionItem,客户端要执行的事务信息,启动activity |
以上就是一个 普通Activity 启动的完整流程。
为啥我说 “普通Activity” 呢?因为你会发现,整个流程是从startActivity这个方法开始的,是我们在一个Activity里面启动另一个Activity的情况。那么第一个Activity,即 根Activity 是如何启动的呢?
另外还注意到,在ActivityStackSupervisor的startSpecificActivityLocked方法中,上面分析有提到,有个判断条件if (wpc != null && wpc.hasThread()),意思是 是否启动了应用进程,而我们只分析了已启动应用进程的情况。那么未启动应用进程的情况就是根Activity的启动了。下面就来了解根Activity的启动,也可以理解为应用程序的启动过程。
三、根Activity的启动—应用进程启动
我们知道,想要启动一个应用程序(App),需要点击手机桌面的应用图标。Android系统的桌面叫做Launcher,有以下作用:
- 作为Android系统的启动器,用于启动应用程序。
- 作为Android系统的桌面,用于显示和管理应用程序的快捷图标和其他桌面组件。
Launcher本身也是一个应用程序,它在启动过程中会请求PackageManageService(系统的包管理服务)返回系统中已经安装的app的信息,并将其用快捷图标展示在桌面屏幕上,用户可以点击图标启动app。例如华为手机的Launcher就是 “华为桌面” 这个系统app。
3.1 应用进程的创建
当点击app图标后,Launcher会在桌面activity(此activity就叫Launcher)内调用startActivitySafely方法,startActivitySafely方法会调用startActivity方法。接下来的部分就和上面分析的 Activity启动的发起 过程一致了,即通过IPC走到了ATMS,直到ActivityStackSupervisor的startSpecificActivityLocked方法中对应用进程是否存在的判断。我们再次瞅瞅:
void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
// Is this activity's application already running?
final WindowProcessController wpc =
mService.getProcessController(r.processName, r.info.applicationInfo.uid);
boolean knownToBeDead = false;
if (wpc != null && wpc.hasThread()) {
try {
//有应用进程就启动activity
realStartActivityLocked(r, wpc, andResume, checkConfig);
return;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting activity "
+ r.intent.getComponent().flattenToShortString(), e);
}
knownToBeDead = true;
}
...
try {
if (Trace.isTagEnabled(TRACE_TAG_ACTIVITY_MANAGER)) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "dispatchingStartProcess:"
+ r.processName);
}
// Post message to start process to avoid possible deadlock of calling into AMS with the
// ATMS lock held.
// 上面的wpc != null && wpc.hasThread()不满足的话,说明没有进程,就会去创建进程
final Message msg = PooledLambda.obtainMessage(
ActivityManagerInternal::startProcess, mService.mAmInternal, r.processName,
r.info.applicationInfo, knownToBeDead, "activity", r.intent.getComponent());
mService.mH.sendMessage(msg);
} finally {
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
}
逻辑很清晰:有应用进程就启动activity(普通activity),没有就去创建进程(然后再启动根activity)。
应用进程存在的判断条件是:wpc != null && wpc.hasThread(),看下WindowProcessController的hasThread方法:
// The actual proc... may be null only if 'persistent' is true (in which case we are in the
// process of launching the app)
private IApplicationThread mThread;
boolean hasThread() {
return mThread != null;
}
前面已有说明,IApplicationThread是ApplicationThread在客户端(app)在服务端(系统进程)的代理,这里判断 IApplicationThread不为空 就代表进程已存在,为啥这么判断呢?这里先猜测,进程创建后,一定会有给IApplicationThread赋值的操作,这样就符合这个逻辑了。我们继续看,瞅瞅进程是如何创建的,以及创建后是否有给IApplicationThread赋值的操作。
使用ActivityTaskManagerService的mH(继承handler)发送了一个消息,消息中第一个参数是ActivityManagerInternal::startProcess,ActivityManagerInternal的实现是AMS的内部类LocalService,LocalService的startProcess方法调用了AMS的startProcessLocked方法,那么我们就看看AMS 的startProcessLocked方法,这里应该就是创建进程了:
final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, boolean knownToBeDead, int intentFlags, HostingRecord hostingRecord, boolean allowWhileBooting, boolean isolated, boolean keepIfLarge) {
return mProcessList.startProcessLocked(processName, info, knownToBeDead, intentFlags,
hostingRecord, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
null /* crashHandler */);
}
这里调用了ProcessList.startProcessLocked方法,内部又多次调用了startProcessLocked不同的重载方法,最后走到startProcess方法:
private Process.ProcessStartResult startProcess(HostingRecord hostingRecord, String entryPoint, ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal, String seInfo, String requiredAbi, String instructionSet, String invokeWith, long startTime) {
try {
...
startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, runtimeFlags, mountExternal,
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
app.info.dataDir, invokeWith, app.info.packageName,
new String[] {PROC_START_SEQ_IDENT + app.startSeq});
}
checkSlow(startTime, "startProcess: returned from zygote!");
return startResult;
} finally {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
}
调用了Process.start方法,跟进看下:
public static ProcessStartResult start(@NonNull final String processClass,
@Nullable final String niceName,
int uid, int gid, @Nullable int[] gids,
int runtimeFlags,
int mountExternal,
int targetSdkVersion,
@Nullable String seInfo,
@NonNull String abi,
@Nullable String instructionSet,
@Nullable String appDataDir,
@Nullable String invokeWith,
@Nullable String packageName,
@Nullable String[] zygoteArgs) {
return ZYGOTE_PROCESS.start(processClass, niceName, uid, gid, gids,
runtimeFlags, mountExternal, targetSdkVersion, seInfo,
abi, instructionSet, appDataDir, invokeWith, packageName,
/*useUsapPool=*/ true, zygoteArgs);
}
ZYGOTE_PROCESS是用于保持与Zygote进程的通信状态,发送socket请求与Zygote进程通信。Zygote进程是进程孵化器,用于创建进程。ZYGOTE_PROCESS的start就不再跟进去了,关于这块知识可以参考《Android进阶解密》第二章、第三章。我们只需要知道其内部:
- Zygote通过fork创建了一个进程
- 在新建的进程中创建Binder线程池(此进程就支持了Binder IPC)
- 最终是通过反射获取到了ActivityThread类并执行了main方法
3.2 根Activity的启动
在之前文章 Handler:Android消息机制–《Android开发艺术探索》阅读笔记——第十章 中介绍主线程的消息机制时就介绍过ActivityThread的main方法,主要就是开启了主线程的消息循环。
final H mH = new H();
public static void main(String[] args) {
...
//1、准备主线程的Looper
Looper.prepareMainLooper();
long startSeq = 0;
if (args != null) {
for (int i = args.length - 1; i >= 0; --i) {
if (args[i] != null && args[i].startsWith(PROC_START_SEQ_IDENT)) {
startSeq = Long.parseLong(
args[i].substring(PROC_START_SEQ_IDENT.length()));
}
}
}
//这里实例化ActivityThread,也就实例化了上面的mH,就是handler。
ActivityThread thread = new ActivityThread();
thread.attach(false, startSeq);
//获取handler
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
...
//主线程looper开启
Looper.loop();
//因为主线程的Looper是不能退出的,退出就无法接受事件了。一旦意外退出,会抛出异常
throw new RuntimeException("Main thread loop unexpectedly exited");
}
在这理,我们关注 这两这行代码:
ActivityThread thread = new ActivityThread();
thread.attach(false, startSeq);
创建ActivityThread实例,同时会创建ApplicationThread实例,ApplicationThread实例是ActivityThread实例的属性。然后调用了attach方法:
private void attach(boolean system, long startSeq) {
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) {
android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
UserHandle.myUserId());
RuntimeInit.setApplicationObject(mAppThread.asBinder());
final IActivityManager mgr = ActivityManager.getService();
try {
//把ApplicationThread实例关联到AMS中
mgr.attachApplication(mAppThread, startSeq);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
...
}
...
}
前面提到过这里mgr就是AMS在客户端的代理,所以mgr的attachApplication方法,就是IPC的走到AMS的attachApplication方法了:
public final void attachApplication(IApplicationThread thread, long startSeq) {
synchronized (this) {
int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
attachApplicationLocked(thread, callingPid, callingUid, startSeq);
Binder.restoreCallingIdentity(origId);
}
}
attachApplicationLocked方法很长,这里保留重要的几点:
private final boolean attachApplicationLocked(IApplicationThread thread, int pid, int callingUid, long startSeq) {
...
//1、IPC操作,创建绑定Application
thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
null, null, null, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.isPersistent(),
new Configuration(app.getWindowProcessController().getConfiguration()),
app.compat, getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked(),
buildSerial, autofillOptions, contentCaptureOptions);
...
// 2、赋值IApplicationThread
app.makeActive(thread, mProcessStats);
...
// See if the top visible activity is waiting to run in this process...
if (normalMode) {
try {
//3、通过ATMS启动 根activity
didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
} catch (Exception e) {
Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
badApp = true;
}
}
...
}
AMS的attachApplicationLocked方法主要三件事:
- 调用IApplicationThread的bindApplication方法,IPC操作,创建绑定Application;
- 通过makeActive方法赋值IApplicationThread,即验证了上面的猜测(创建进程后赋值);
- 通过ATMS启动 根activity
先看makeActive方法:
public void makeActive(IApplicationThread _thread, ProcessStatsService tracker) {
...
thread = _thread;
mWindowProcessController.setThread(thread);
}
看到使用mWindowProcessController.setThread(thread)确实完成了IApplicationThread的赋值。这样就可以依据IApplicationThread是否为空判断进程是否存在了。
再看创建绑定Application的过程:IApplicationThread的bindApplication方法实现是客户端的ApplicationThread的bindApplication方法,它又使用H转移到了ActivityThread的handleBindApplication方法(从Binder线程池转移到主线程),看下handleBindApplication方法:
private void handleBindApplication(AppBindData data) {
...
final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
appContext.getClassLoader(), false, true, false);
final ContextImpl instrContext = ContextImpl.createAppContext(this, pi,
appContext.getOpPackageName());
try {
//创建Instrumentation
final ClassLoader cl = instrContext.getClassLoader();
mInstrumentation = (Instrumentation)
cl.loadClass(data.instrumentationName.getClassName()).newInstance();
}
...
final ComponentName component = new ComponentName(ii.packageName, ii.name);
mInstrumentation.init(this, instrContext, appContext, component,
data.instrumentationWatcher, data.instrumentationUiAutomationConnection);
...
//创建Application
app = data.info.makeApplication(data.restrictedBackupMode, null);
...
mInitialApplication = app;
try {
mInstrumentation.onCreate(data.instrumentationArgs);
}
...
try {
//内部调用Application的onCreate方法
mInstrumentation.callApplicationOnCreate(app);
}
...
}
主要就是创建Application,并且调用生命周期onCreate方法。你会发现在前面介绍的ActivityThread的performLaunchActivity方法中,也有同样的操作,只不过会先判断Application是否已存在。也就是说,正常情况下Application的初始化是在handleBindApplication方法中的,并且是创建进程后调用的。performLaunchActivity中只是做了一个检测,异常情况Application不存在时才会创建。
这里注意一点,创建Application后,内部会attach方法,attach内部会调用attachBaseContext方法,attachBaseContext方法是我们能接触到的一个方法,接着才是onCreate方法。
再来看 根activity 的启动,回到上面AMS的attachApplicationLocked方法,调用了mAtmInternal.attachApplication方法,mAtmInternal是ActivityTaskManagerInternal实例,具体实现是在ActivityTaskManagerService的内部类LocalService,去看看:
//ActivityTaskManagerService#LocalService
public boolean attachApplication(WindowProcessController wpc) throws RemoteException {
synchronized (mGlobalLockWithoutBoost) {
return mRootActivityContainer.attachApplication(wpc);
}
}
mRootActivityContainer是RootActivityContainer实例,看下它的attachApplication方法:
boolean attachApplication(WindowProcessController app) throws RemoteException {
final String processName = app.mName;
boolean didSomething = false;
for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
final ActivityDisplay display = mActivityDisplays.get(displayNdx);
final ActivityStack stack = display.getFocusedStack();
if (stack != null) {
stack.getAllRunningVisibleActivitiesLocked(mTmpActivityList);
final ActivityRecord top = stack.topRunningActivityLocked();
final int size = mTmpActivityList.size();
for (int i = 0; i < size; i++) {
final ActivityRecord activity = mTmpActivityList.get(i);
if (activity.app == null && app.mUid == activity.info.applicationInfo.uid
&& processName.equals(activity.processName)) {
try {
if (mStackSupervisor.realStartActivityLocked(activity, app,
top == activity /* andResume */, true /* checkConfig */)) {
didSomething = true;
}
}
...
}
}
}
}
if (!didSomething) {
ensureActivitiesVisible(null, 0, false /* preserve_windows */);
}
return didSomething;
}
遍历activity栈,此时理论上应该只有一个根activity,然后调用mStackSupervisor.realStartActivityLocked方法,看到这里我们知道了,这里就开始走上面分析过的流程了,即使用ClientTransaction会跨进程交给客户端,然后就是2.3、2.4两个小节的内容。
嗯,到这里根activity的启动流程也分析完了。
我们发现,根activity的启动前 需要创建应用进程,然后走到ActivityThread的main方法,开启主线程循环,初始化并绑定Application、赋值IApplicationThread,最后真正的启动过程和普通Activity是一致的。
上面的流程图 补充 根activity的逻辑,完整关系如下:
总结
关于 普通Activity 启动的流程的讲解,我们分成了几个阶段:启动的发起、AMS的管理、线程切换、启动核心实现,知道了启动过程经历了两次IPC,客户端到AMS、AMS到客户端,以及Activity创建和生命周期的执行。 然后又在此基础上 补充的根activity的启动:先创建应用进程,再绑定Application,最后真正启动跟Activity。
本篇内容涉及大量知识点,结合 IPC、Handler、Window等相关知识,这样可以对Android系统有更加完整的认识。
好了,今天就到这里,欢迎留言讨论~
你的 点赞、评论、收藏、转发,是对我的巨大鼓励!
欢迎关注我的 公 众 号:
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/13095.html