目錄
Android應(yīng)用啟動之從Launcher拉起APP(一)
Android應(yīng)用啟動之從Launcher拉起APP(二)
Android應(yīng)用啟動之從Launcher拉起APP(三)
Android應(yīng)用啟動之從Launcher拉起APP時序圖
從桌面點擊圖標(biāo)
程序的啟動,一般都是從桌面點擊圖標(biāo)開始的。
發(fā)生點擊后遗淳,響應(yīng)函數(shù):
protected void onClickAppShortcut(final View v) {
……
final ShortcutInfo shortcut = (ShortcutInfo) tag;
……
// Check for abandoned promise
if ((v instanceof BubbleTextView) && shortcut.isPromise()) {
String packageName = shortcut.intent.getComponent() != null ?
shortcut.intent.getComponent().getPackageName() : shortcut.intent.getPackage();
if (!TextUtils.isEmpty(packageName)) {
onClickPendingAppItem(v, packageName,
shortcut.hasStatusFlag(ShortcutInfo.FLAG_INSTALL_SESSION_ACTIVE));
return;
}
}
// 進(jìn)入啟動
startAppShortcutOrInfoActivity(v);
}
private void startAppShortcutOrInfoActivity(View v) {
ItemInfo item = (ItemInfo) v.getTag();
Intent intent = item.getIntent();
if (intent == null) {
throw new IllegalArgumentException("Input must have a valid intent");
}
// 啟動activity
boolean success = startActivitySafely(v, intent, item);
getUserEventDispatcher().logAppLaunch(v, intent); // TODO for discovered apps b/35802115
if (success && v instanceof BubbleTextView) {
mWaitingForResume = (BubbleTextView) v;
mWaitingForResume.setStayPressed(true);
}
}
最后執(zhí)行到startActivitySafely函數(shù):
public boolean startActivitySafely(View v, Intent intent, ItemInfo item) {
……
boolean useLaunchAnimation = (v != null) &&
!intent.hasExtra(INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION);
Bundle optsBundle = useLaunchAnimation ? getActivityLaunchOptions(v) : null;
UserHandle user = item == null ? null : item.user;
// 添加new task图仓,這樣就啟動了根activity
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if (v != null) {
intent.setSourceBounds(getViewBounds(v));
}
try {
if (Utilities.ATLEAST_MARSHMALLOW
&& (item instanceof ShortcutInfo)
&& (item.itemType == Favorites.ITEM_TYPE_SHORTCUT
|| item.itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT)
&& !((ShortcutInfo) item).isPromise()) {
startShortcutIntentSafely(intent, optsBundle, item);
} else if (user == null || user.equals(Process.myUserHandle())) {
// 啟動activity
startActivity(intent, optsBundle);
} else {
LauncherAppsCompat.getInstance(this).startActivityForProfile(
intent.getComponent(), user, intent.getSourceBounds(), optsBundle);
}
return true;
} catch (ActivityNotFoundException|SecurityException e) {
Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
Log.e(TAG, "Unable to launch. tag=" + item + " intent=" + intent, e);
}
return false;
}
函數(shù)中添加了FLAG_ACTIVITY_NEW_TASK扣甲,并且執(zhí)行了startActivity函數(shù)己莺。
startActivity函數(shù)在Activity.java中:
public void startActivity(Intent intent, @Nullable Bundle options) {
if (options != null) {
startActivityForResult(intent, -1, options);
} else {
startActivityForResult(intent, -1);
}
}
startActivityForResult函數(shù)笤休,第二個參數(shù)為-1尖飞,表示Launcher不關(guān)心返回值:
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
// 根Activity所以mParent == null
if (mParent == null) {
options = transferSpringboardActivityOptions(options);
// 繼續(xù)執(zhí)行startActivity
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 {
if (options != null) {
mParent.startActivityFromChild(this, intent, requestCode, options);
} else {
mParent.startActivityFromChild(this, intent, requestCode);
}
}
}
接下來就執(zhí)行到了Instrumentation.java
的execStartActivity函數(shù):
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;
}
execStartActivity最后會執(zhí)行ActivityManager.getService().startActivity
函數(shù)
ActivityManager.java是一個AIDL文件生成的類,文件路徑:ActivityManager.aidl
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;
}
};
通過這種方式最后就執(zhí)行到了AMS的startActivity函數(shù)店雅。
從AMS到ActivityThread
進(jìn)入AMS后政基,首先執(zhí)行startActivity函數(shù):
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());
}
startActivity調(diào)用了startActivityAsUser函數(shù),其中主要添加了參數(shù)UserHandle.getCallingUserId()闹啦,用來獲取user id.
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) {
// 檢查是否是被掛起
enforceNotIsolatedCaller("startActivity");
// 檢查用戶權(quán)限
userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
userId, false, ALLOW_FULL_ONLY, "startActivity", null);
// 執(zhí)行startActivity
return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
profilerInfo, null, null, bOptions, false, userId, null, null,
"startActivityAsUser");
}
ActivityStarter.java中執(zhí)行startActivityMayWait函數(shù):
final 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, Bundle bOptions, boolean ignoreTargetSecurity, int userId,
IActivityContainer iContainer, TaskRecord inTask, String reason) {
……
final ActivityRecord[] outRecord = new ActivityRecord[1];
int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,
aInfo, rInfo, voiceSession, voiceInteractor,
resultTo, resultWho, requestCode, callingPid,
callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
options, ignoreTargetSecurity, componentSpecified, outRecord, container,
inTask, reason);
……
}
ActivityStarter類是加載Activity的控制類沮明。
int startActivityLocked(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, ActivityStackSupervisor.ActivityContainer container,
TaskRecord inTask, String reason) {
// 判斷啟動理由
if (TextUtils.isEmpty(reason)) {
throw new IllegalArgumentException("Need to specify a reason.");
}
mLastStartReason = reason;
mLastStartActivityTimeMs = System.currentTimeMillis();
mLastStartActivityRecord[0] = null;
// 執(zhí)行startActivity
mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
container, inTask);
if (outActivity != null) {
outActivity[0] = mLastStartActivityRecord[0];
}
return mLastStartActivityResult;
}
最后又執(zhí)行到了startActivity函數(shù):
// 創(chuàng)建ActivityRecord
ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
mSupervisor, container, options, sourceRecord);
if (outActivity != null) {
outActivity[0] = r;
}
if (r.appTimeTracker == null && sourceRecord != null) {
// If the caller didn't specify an explicit time tracker, we want to continue
// tracking under any it has.
r.appTimeTracker = sourceRecord.appTimeTracker;
}
……
if (mService.mDidAppSwitch) {
// This is the second allowed switch since we stopped switches,
// so now just generally allow switches. Use case: user presses
// home (switches disabled, switch to home, mDidAppSwitch now true);
// user taps a home icon (coming from home so allowed, we hit here
// and now allow anyone to switch again).
mService.mAppSwitchesAllowedTime = 0;
} else {
mService.mDidAppSwitch = true;
}
doPendingActivityLaunchesLocked(false);
// 繼續(xù)執(zhí)行startActivity
return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true,
options, inTask, outActivity);
}
最后還是執(zhí)行startActivity函數(shù):
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 (!ActivityManager.isStartResultSuccessful(result)
&& mStartActivity.getTask() != null) {
mStartActivity.getTask().removeActivity(mStartActivity);
}
mService.mWindowManager.continueSurfaceLayout();
}
postStartActivityProcessing(r, result, mSupervisor.getLastStack().mStackId, mSourceRecord,
mTargetStack);
return result;
}
繼續(xù)執(zhí)行startActivityUnchecked函數(shù):
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
ActivityRecord[] outActivity) {
……
int result = START_SUCCESS;
if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
&& (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
newTask = true;
// 創(chuàng)建新的task(新的Activity堆棧)
result = setTaskFromReuseOrCreateNewTask(
taskToAffiliate, preferredLaunchStackId, topStack);
} else if (mSourceRecord != null) {
……
}
……
mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,
mOptions);
if (mDoResume) {
……
} else {
if (mTargetStack.isFocusable() && !mSupervisor.isFocusedStack(mTargetStack)) {
mTargetStack.moveToFront("startActivityUnchecked");
}
mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
mOptions);
}
} else {
mTargetStack.addRecentActivityLocked(mStartActivity);
}
……
return START_SUCCESS;
}
接下來就執(zhí)行到里ActivityStackSupervisor.java的resumeFocusedStackTopActivityLocked函數(shù):
boolean resumeFocusedStackTopActivityLocked(
ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
if (!readyToResume()) {
return false;
}
if (targetStack != null && isFocusedStack(targetStack)) {
return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}
final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
if (r == null || !r.isState(RESUMED)) {
mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
} else if (r.isState(RESUMED)) {
mFocusedStack.executeAppTransition(targetOptions);
}
return false;
}
又執(zhí)行回去的resumeTopActivityUncheckedLocked函數(shù):
boolean resumeFocusedStackTopActivityLocked(
ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
if (targetStack != null && isFocusedStack(targetStack)) {
return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}
final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
if (r == null || r.state != RESUMED) {
mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
} else if (r.state == RESUMED) {
mFocusedStack.executeAppTransition(targetOptions);
}
return false;
}
繼續(xù)執(zhí)行ActivityStack.java
里的resumeTopActivityUncheckedLocked函數(shù):
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
if (mStackSupervisor.inResumeTopActivity) {
return false;
}
boolean result = false;
try {
mStackSupervisor.inResumeTopActivity = true;
// 執(zhí)行resumeTopActivityInnerLocked方法
result = resumeTopActivityInnerLocked(prev, options);
final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
if (next == null || !next.canTurnScreenOn()) {
checkReadyForSleep();
}
} finally {
mStackSupervisor.inResumeTopActivity = false;
}
return result;
}
繼續(xù)執(zhí)行resumeTopActivityInnerLocked方法:
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
……
try {
next.completeResumeLocked();
} catch (Exception e) {
// If any exception gets thrown, toss away this
// activity and try the next one.
Slog.w(TAG, "Exception thrown during resume of " + next, e);
requestFinishActivityLocked(next.appToken, Activity.RESULT_CANCELED, null,
"resume-exception", true);
if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
return true;
}
} else {
……
if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Restarting " + next);
mStackSupervisor.startSpecificActivityLocked(next, true, true);
}
if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
return true;
}
然后執(zhí)行到了startSpecificActivityLocked函數(shù)(有點麻木了,這一個個跳轉(zhuǎn)的):
void startSpecificActivityLocked(ActivityRecord r,
boolean andResume, boolean checkConfig) {
// 獲取將要啟動Activity所在的應(yīng)用程序進(jìn)程
ProcessRecord app = mService.getProcessRecordLocked(r.processName,
r.info.applicationInfo.uid, true);
r.getStack().setLaunchTime(r);
// 如果App已經(jīng)啟動
if (app != null && app.thread != null) {
try {
if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
|| !"android".equals(r.info.packageName)) {
app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
mService.mProcessStats);
}
// 執(zhí)行開始Activity
realStartActivityLocked(r, app, andResume, checkConfig);
return;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting activity "
+ r.intent.getComponent().flattenToShortString(), e);
}
}
// 如果app沒有啟動窍奋,就啟動app
mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
"activity", r.intent.getComponent(), false, false, true);
}
realStartActivityLocked函數(shù):
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
boolean andResume, boolean checkConfig) throws RemoteException {
……
// app是應(yīng)用進(jìn)行描述荐健,app.thread是binder
app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
System.identityHashCode(r), r.info,
mergedConfiguration.getGlobalConfiguration(),
mergedConfiguration.getOverrideConfiguration(), r.compat,
r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
r.persistentState, results, newIntents, !andResume,
mService.isNextTransitionForward(), profilerInfo);
……
} catch (RemoteException e) {
……
}
……
return true;
}
這樣就又調(diào)用到了應(yīng)用程序內(nèi)部的ApplicationThread中酱畅。