由于各种原因,Activity启动流程的研究被一直延后,最近终于腾出时间,但现在都已经是Android P
了,Android Q
的各种爆料也是频出,索性,研究的源码版本升至Android 9
,之前的源码研究意义也就没那么大了
和8.0
不同的是,应用图标点击事件更纯粹,之前的点击事件应用图标和三大金刚的点击入口相同。而点击事件的类为com.android.launcher3.touch.ItemClickHandler
public class ItemClickHandler {
public static final OnClickListener INSTANCE = ItemClickHandler::onClick;
private static void onClick(View v) {
......
Object tag = v.getTag();
if (tag instanceof ShortcutInfo) {
onClickAppShortcut(v, (ShortcutInfo) tag, launcher);
......
}
......
private static void onClickAppShortcut(View v, ShortcutInfo shortcut, Launcher launcher) {
......
// Start activities
startAppShortcutOrInfoActivity(v, shortcut, launcher);
}
private static void startAppShortcutOrInfoActivity(View v, ItemInfo item, Launcher launcher) {
......
launcher.startActivitySafely(v, intent, item);
}
}
看吧,最终还是回到了com.android.launcher3.Launcher
的startActivitySafely方法
public class Launcher extends BaseDraggingActivity implements LauncherExterns,
LauncherModel.Callbacks, LauncherProviderChangeListener, UserEventDelegate{
......
public boolean startActivitySafely(View v, Intent intent, ItemInfo item) {
boolean success = super.startActivitySafely(v, intent, item);
if (success && v instanceof BubbleTextView) {
// This is set to the view that launched the activity that navigated the user away
// from launcher. Since there is no callback for when the activity has finished
// launching, enable the press state and keep this reference to reset the press
// state when we return to launcher.
BubbleTextView btv = (BubbleTextView) v;
btv.setStayPressed(true);
setOnResumeCallback(btv);
}
return success;
}
......
}
看来,重点还是在super.startActivitySafely(v, intent, item)
public abstract class BaseDraggingActivity extends BaseActivity
implements WallpaperColorInfo.OnChangeListener {
......
public boolean startActivitySafely(View v, Intent intent, ItemInfo item) {
......
} else if (user == null || user.equals(Process.myUserHandle())) {
// Could be launching some bookkeeping activity
startActivity(intent, optsBundle);
......
}
......
}
下一步,就是调用应用层开发非常熟悉的android.app.Activity
中的startActivity
方法了
接下来,就是进入启动应用的流程了
public class Activity extends ContextThemeWrapper
implements LayoutInflater.Factory2,
Window.Callback, KeyEvent.Callback,
OnCreateContextMenuListener, ComponentCallbacks2,
Window.OnWindowDismissedCallback, WindowControllerCallback,
AutofillManager.AutofillClient {
......
private Instrumentation mInstrumentation;
......
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
......
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
......
}
......
public void startActivity(Intent intent, @Nullable Bundle options) {
if (options != null) {
startActivityForResult(intent, -1, options);
} else {
// Note we want to go through this call for compatibility with
// applications that may have overridden the method.
startActivityForResult(intent, -1);
}
}
......
}
这里,最终执行到了Instrumentation
对象的execStartActivity
方法,至此,从startActivityForResult
方法内部开始,就进入了漫长的启动流程,等回调回来,启动流程也就结束了
public class Instrumentation {
......
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
......
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess(who);
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;
}
......
}
@SystemService(Context.ACTIVITY_SERVICE)
public class ActivityManager {
......
/**
* @hide
*/
public static IActivityManager getService() {
return IActivityManagerSingleton.get();
}
......
}
这个接口最终返回的是一个IActivityManager
的对象,而进一步跟踪发现,IActivityManager
是一个aidl文件,毫无疑问,从这里开始,要进行跨进程通信了,而最终是在system_process进程中启动应用的。根据aidl的开发规则,最终实现接口需要继承编译后生成的IActivityManager.Stub
抽象类,那么就好办了,用Android Studio
跟踪一下有哪些类继承了这个抽象类。
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)
.execute();
}
......
}
class ActivityStarter {
......
int execute() {
......
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,
mRequest.originatingPendingIntent);
......
}
......
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,
PendingIntentRecord originatingPendingIntent) {
......
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, originatingPendingIntent);
......
}
......
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,
PendingIntentRecord originatingPendingIntent) {
......
return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
true /* doResume */, checkedOptions, inTask, outActivity);
}
......
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,
PendingIntentRecord originatingPendingIntent) {
......
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, originatingPendingIntent);
......
}
......
private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
ActivityRecord[] outActivity) {
......
result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, doResume, options, inTask, outActivity);
......
}
// 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) {
......
mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,
mOptions);
......
mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
mOptions);
......
}
}
总之就是各种startActivity,目前为止的流程时序图如下:
AMS是ActivityManagerService的缩写
这样一看就很清楚了,但还没完,继续接下来的源码分析
package com.android.server.am;
......
public class ActivityStackSupervisor extends ConfigurationContainer implements DisplayListener,
RecentTasks.Callbacks {
......
boolean pauseBackStacks(boolean userLeaving, ActivityRecord resuming, boolean dontWait) {
......
someActivityPaused |= stack.startPausingLocked(userLeaving, false, resuming,
dontWait);
......
}
......
boolean resumeFocusedStackTopActivityLocked(
ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
if (!readyToResume()) {
return false;
}
if (targetStack != null && isFocusedStack(targetStack)) {
return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}
......
}
}
package com.android.server.am;
......
class ActivityStack<T extends StackWindowController> extends ConfigurationContainer
implements StackWindowListener {
......
final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,
ActivityRecord resuming, boolean pauseImmediately) {
......
if (prev.app != null && prev.app.thread != null) {
......
mService.getLifecycleManager().scheduleTransaction(prev.app.thread, prev.appToken,
PauseActivityItem.obtain(prev.finishing, userLeaving,
prev.configChangeFlags, pauseImmediately));
......
}
......
}
......
@GuardedBy("mService")
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
......
result = resumeTopActivityInnerLocked(prev, options);
......
}
......
@GuardedBy("mService")
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
......
boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, next, false);
......
}
......
}
package com.android.server.am;
......
class ClientLifecycleManager {
......
void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
final IApplicationThread client = transaction.getClient();
transaction.schedule();
if (!(client instanceof Binder)) {
// If client is not an instance of Binder - it's a remote call and at this point it is
// safe to recycle the object. All objects used for local calls will be recycled after
// the transaction is executed on client in ActivityThread.
transaction.recycle();
}
}
void scheduleTransaction(@NonNull IApplicationThread client, @NonNull IBinder activityToken,
@NonNull ActivityLifecycleItem stateRequest) throws RemoteException {
final ClientTransaction clientTransaction = transactionWithState(client, activityToken,
stateRequest);
scheduleTransaction(clientTransaction);
}
......
}
package android.app.servertransaction;
......
public class ClientTransaction implements Parcelable, ObjectPoolItem {
......
private IApplicationThread mClient;
......
public void schedule() throws RemoteException {
mClient.scheduleTransaction(this);
}
......
}
进入到这里,就感觉,正戏快要登场了,稍一跟踪,发现IApplicationThread
也是一个aidl文件,同上边的IActivityManager
原理一样,最终跟踪到了ActivityThread$ApplicationThread
,显然,接下来的步骤就不在system_process进程中执行了,而是回到了com.android.launcher3进程
package android.app;
......
public final class ActivityThread extends ClientTransactionHandler {
......
final H mH = new H();
......
private final TransactionExecutor mTransactionExecutor = new TransactionExecutor(this);
......
private class ApplicationThread extends IApplicationThread.Stub {
......
@Override
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
ActivityThread.this.scheduleTransaction(transaction);
}
}
......
class H extends Handler {
......
public static final int EXECUTE_TRANSACTION = 159;
......
public void handleMessage(Message msg) {
......
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();
}
// TODO(lifecycler): Recycle locally scheduled transactions.
break;
......
}
}
......
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);
}
......
}
package android.app;
......
public abstract class ClientTransactionHandler {
// Schedule phase related logic and handlers.
/** Prepare and schedule transaction for execution. */
void scheduleTransaction(ClientTransaction transaction) {
transaction.preExecute(this);
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
......
abstract void sendMessage(int what, Object obj);
......
}
到了这里,通过Handler
来调度处理任务,接下来就是执行到了TransactionExecutor#execute
中
package android.app.servertransaction;
......
public class TransactionExecutor {
......
public void execute(ClientTransaction transaction) {
final IBinder token = transaction.getActivityToken();
log("Start resolving transaction for client: " + mTransactionHandler + ", token: " + token);
executeCallbacks(transaction);
executeLifecycleState(transaction);
mPendingActions.clear();
log("End resolving transaction");
}
/** Cycle through all states requested by callbacks and execute them at proper times. */
@VisibleForTesting
public void executeCallbacks(ClientTransaction transaction) {
......
final ClientTransactionItem item = callbacks.get(i);
......
item.execute(mTransactionHandler, token, mPendingActions);
......
}
......
}
同样的,流程时序图梳理一下
ASS是ActivityStackSupervisor的缩写
CLM是ClientLifecycleManager的缩写
ApplicationThread是ActivityThread的内部类
执行ActivityStack中的第20步之前,会先进行函数返回值一系列操作,毕竟,第20步是通过Handler调度之后执行的
上面的流程已经分成了两条异步线路在同时执行了,一条是继续在system_process进程中执行,另一条就是调度分流在com.android.launcher3进程中执行的线路,但调试发现,在调度分流线路中,执行到ActivityThread#sendMessage()
后,就不再执行ActivityThread$H#handleMessage(Message)
中的内容了,不知道为什么,后续待验证,那么继续看主线接下来的执行路线,不过,在继续主线之前,先有一系列的函数返回操作
ASS是ActivityStackSupervisor的缩写
ActivityStackHandler是ActivityStack的内部类,继承自Handler
经过一系列的值返回回调后,回到主线
上面设计到了应用进程的创建,这个就作为下一个课题来研究吧.接下来,就是在应用进程中执行,默认情况下,应用进程名就是应用包名,即applicationId
时序图到了这里,主体流程就已经解读完成了,下面是一些之前研究的代码片段,后续再补充进去
package android.app.servertransaction;
......
public class LaunchActivityItem extends ClientTransactionItem {
......
@Override
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);
client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
......
}
毫无疑问,这里的client
就是上面的ActivityThread
对象
package android.app;
......
public final class ActivityThread extends ClientTransactionHandler {
......
Instrumentation mInstrumentation;
......
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
......
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
......
}
......
@Override
public Activity handleLaunchActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions, Intent customIntent) {
......
final Activity a = performLaunchActivity(r, customIntent);
......
}
......
接下来就执行回Instrumentation
对象中了,绕了好一个大圈啊,而且从方法名不难看出一些端倪
package android.app;
......
public class Instrumentation {
......
public void callActivityOnCreate(Activity activity, Bundle icicle) {
prePerformCreate(activity);
activity.performCreate(icicle);
postPerformCreate(activity);
}
......
}
package android.app;
......
public class Activity extends ContextThemeWrapper
implements LayoutInflater.Factory2,
Window.Callback, KeyEvent.Callback,
OnCreateContextMenuListener, ComponentCallbacks2,
Window.OnWindowDismissedCallback, WindowControllerCallback,
AutofillManager.AutofillClient {
......
final void performCreate(Bundle icicle) {
performCreate(icicle, null);
}
final void performCreate(Bundle icicle, PersistableBundle persistentState) {
mCanEnterPictureInPicture = true;
restoreHasCurrentPermissionRequest(icicle);
if (persistentState != null) {
onCreate(icicle, persistentState);
} else {
onCreate(icicle);
}
writeEventLog(LOG_AM_ON_CREATE_CALLED, "performCreate");
mActivityTransitionState.readState(icicle);
mVisibleFromClient = !mWindow.getWindowStyle().getBoolean(
com.android.internal.R.styleable.Window_windowNoDisplay, false);
mFragments.dispatchActivityCreated();
mActivityTransitionState.setEnterActivityOptions(this, getActivityOptions());
}
......
}
执行到这一步,就回调到了应用层中再熟悉不过的Activity#onCreate
了,这个startActivity的调试流程终于算是通了,当然,中间的很多细节都还需要后续再深入研究