2017年的时候初次学习了下Activity启动流程,最近在复习这个功能知识点的时候,发现忘记了许多,然后看了许多博客和书籍的资料,重新画了一个流程图,对照流程图源码流程就不会忘记的太快了。
我们现在来跟着流程图走一遍:首先是startActivity 然后会走到如下的方法:
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) {
// If this start is requesting a result, we can avoid making
// the activity visible until the result is received. Setting
// this code during onCreate(Bundle savedInstanceState) or onResume() will keep the
// activity hidden during this time, to avoid flickering.
// This can only be done when a result is requested because
// that guarantees we will get information back when the
// activity is finished, no matter what happens to it.
mStartedActivity = true;
}
cancelInputsAndStartExitTransition(options);
// TODO Consider clearing/flushing other event sources and events for child windows.
} else {
if (options != null) {
mParent.startActivityFromChild(this, intent, requestCode, options);
} else {
// Note we want to go through this method for compatibility with
// existing applications that may have overridden it.
mParent.startActivityFromChild(this, intent, requestCode);
}
}
}
摘取关键代码如下,进入了 Instrumentation 的方法,什么是Instrumentation ?
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
官方:An instrumentation that enables several advanced features and makes some hard guarantees about the state of the application under instrumentation.
初探它有哪些方法:(感兴趣的可以自己去文档看)https://developer.android.google.cn/reference/android/support/test/runner/MonitoringInstrumentation?hl=zh-tw
对了,没错最后的启动操作activity的生命周期的方法还是靠它来执行的!
接着下一步往下走: mInstrumentation.execStartActivity()调用了ActivityManager 里面的方法
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);
}
if (mActivityMonitors != null) {
synchronized (mSync) {
final int N = mActivityMonitors.size();
for (int i=0; i= 0 ? am.getResult() : null;
}
break;
}
}
}
}
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;
}
代码是不是有点多,不要方。看关键的代码:
int result = ActivityManager.getService()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
这里的ActivityManager又是个什么鬼?
官方:This class gives information about, and interacts with, activities, services, and the containing process.A number of the methods in this class are for debugging or informational purposes and they should not be used to affect any runtime behavior of your app. These methods are called out as such in the method level documentation.
这个类我们在开发应该经常用到吧,官方的说明也写了可以拿到app相关的activities, services, and the containing process.不用过多的解释吧
接着往下走:进入ActivityManager里的代码
/**
* @hide
*/
public static IActivityManager getService() {
return IActivityManagerSingleton.get();
}
private static final Singleton IActivityManagerSingleton =
new Singleton() {
@Override
protected IActivityManager create() {
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
final IActivityManager am = IActivityManager.Stub.asInterface(b);
return am;
}
};
我们来看看IActivityManager 是个什么鬼?
看了我的截图,是不是明白了 就是一个aidl啊, 熟系Binder机制的同学可能立马反映过来了 原来是搞事情啊,是进行了进程的的通信啊,没错 ActivityManagerService简称AMS,它是android中很重要的一个服务,它统筹管理着android的四大组件;统一调度各应用进程;AMN由Binder类由Binder类派生,实现了IActivityManager接口,客户端使用ActivityManager类,因为AMS是系统核心服务,很多API不能直接访问,需要通过ActivityManager,ActivityManager内部通过调用AMN的getDefault方法得到一个ActivityManagerProxy对象,通过它可与AMS通信。
熟悉binder的架构就只知道,是基于C/S架构进行通信的, 那么IActivityManager am = IActivityManager.Stub.asInterface(b);相当于是客户端,返回了一个服务端的代理对象,客户端通过代理对象和服务端进行通信。那么
public class ActivityManagerService extends IActivityManager.Stub
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
.....
}
ActivityManagerService 又是IActivityManager.Stub的子类,我们通过这个代理类和系统进程进行通信。
我们在看看ActivityManagerService 的startActivity()
@Override
4461 public final int startActivity(IApplicationThread caller, String callingPackage,
4462 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4463 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4464 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4465 resultWho, requestCode, startFlags, profilerInfo, bOptions,
4466 UserHandle.getCallingUserId());
4467 }
最后调用了startActivityAsUser()
@Override
4490 public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4491 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4492 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4493 enforceNotIsolatedCaller("startActivity");
4494 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4495 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4496 // TODO: Switch to user app stacks here.
4497 return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4498 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4499 profilerInfo, null, null, bOptions, false, userId, null, null,
4500 "startActivityAsUser");
4501 }
又调用了 mActivityStarter.startActivityMayWait() ActivityStarter又是什么?
这个类谷歌文档是木有的,我们只有看源码我们看下它的注释:
133/**
134 * Controller for interpreting how and then launching activities.
135 *
136 * This class collects all the logic for determining how an intent and flags should be turned into
137 * an activity and associated task and stack.
138 */
139class ActivityStarter {.......}
英文不大好大概翻译下:该类收集用于确定如何将intent和标志转换为一个activity以及相关的任务和堆栈。
我们在看下startActivityMayWait()都做了什么事情?
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,
TaskRecord inTask, String reason) {
// Refuse possible leaked file descriptors
if (intent != null && intent.hasFileDescriptors()) {
throw new IllegalArgumentException("File descriptors passed in Intent");
}
mSupervisor.mActivityMetricsLogger.notifyActivityLaunching();
boolean componentSpecified = intent.getComponent() != null;
// Save a copy in case ephemeral needs it
final Intent ephemeralIntent = new Intent(intent);
// Don't modify the client's object!
intent = new Intent(intent);
if (componentSpecified
&& intent.getData() != null
&& Intent.ACTION_VIEW.equals(intent.getAction())
&& mService.getPackageManagerInternalLocked()
.isInstantAppInstallerComponent(intent.getComponent())) {
// intercept intents targeted directly to the ephemeral installer the
// ephemeral installer should never be started with a raw URL; instead
// adjust the intent so it looks like a "normal" instant app launch
intent.setComponent(null /*component*/);
componentSpecified = false;
}
ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId);
if (rInfo == null) {
UserInfo userInfo = mSupervisor.getUserInfo(userId);
if (userInfo != null && userInfo.isManagedProfile()) {
// Special case for managed profiles, if attempting to launch non-cryto aware
// app in a locked managed profile from an unlocked parent allow it to resolve
// as user will be sent via confirm credentials to unlock the profile.
UserManager userManager = UserManager.get(mService.mContext);
boolean profileLockedAndParentUnlockingOrUnlocked = false;
long token = Binder.clearCallingIdentity();
try {
UserInfo parent = userManager.getProfileParent(userId);
profileLockedAndParentUnlockingOrUnlocked = (parent != null)
&& userManager.isUserUnlockingOrUnlocked(parent.id)
&& !userManager.isUserUnlockingOrUnlocked(userId);
} finally {
Binder.restoreCallingIdentity(token);
}
if (profileLockedAndParentUnlockingOrUnlocked) {
rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,
PackageManager.MATCH_DIRECT_BOOT_AWARE
| PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
}
}
}
// Collect information about the target of the Intent.
ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);
ActivityOptions options = ActivityOptions.fromBundle(bOptions);
synchronized (mService) {
final int realCallingPid = Binder.getCallingPid();
final int realCallingUid = Binder.getCallingUid();
int callingPid;
if (callingUid >= 0) {
callingPid = -1;
} else if (caller == null) {
callingPid = realCallingPid;
callingUid = realCallingUid;
} else {
callingPid = callingUid = -1;
}
final ActivityStack stack = mSupervisor.mFocusedStack;
stack.mConfigWillChange = globalConfig != null
&& mService.getGlobalConfiguration().diff(globalConfig) != 0;
if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
"Starting activity when config will change = " + stack.mConfigWillChange);
final long origId = Binder.clearCallingIdentity();
if (aInfo != null &&
(aInfo.applicationInfo.privateFlags
& ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0) {
// This may be a heavy-weight process! Check to see if we already
// have another, different heavy-weight process running.
if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) {
final ProcessRecord heavy = mService.mHeavyWeightProcess;
if (heavy != null && (heavy.info.uid != aInfo.applicationInfo.uid
|| !heavy.processName.equals(aInfo.processName))) {
int appCallingUid = callingUid;
if (caller != null) {
ProcessRecord callerApp = mService.getRecordForAppLocked(caller);
if (callerApp != null) {
appCallingUid = callerApp.info.uid;
} else {
Slog.w(TAG, "Unable to find app for caller " + caller
+ " (pid=" + callingPid + ") when starting: "
+ intent.toString());
ActivityOptions.abort(options);
return ActivityManager.START_PERMISSION_DENIED;
}
}
IIntentSender target = mService.getIntentSenderLocked(
ActivityManager.INTENT_SENDER_ACTIVITY, "android",
appCallingUid, userId, null, null, 0, new Intent[] { intent },
new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT
| PendingIntent.FLAG_ONE_SHOT, null);
Intent newIntent = new Intent();
if (requestCode >= 0) {
// Caller is requesting a result.
newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true);
}
newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT,
new IntentSender(target));
if (heavy.activities.size() > 0) {
ActivityRecord hist = heavy.activities.get(0);
newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP,
hist.packageName);
newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK,
hist.getTask().taskId);
}
newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP,
aInfo.packageName);
newIntent.setFlags(intent.getFlags());
newIntent.setClassName("android",
HeavyWeightSwitcherActivity.class.getName());
intent = newIntent;
resolvedType = null;
caller = null;
callingUid = Binder.getCallingUid();
callingPid = Binder.getCallingPid();
componentSpecified = true;
rInfo = mSupervisor.resolveIntent(intent, null /*resolvedType*/, userId);
aInfo = rInfo != null ? rInfo.activityInfo : null;
if (aInfo != null) {
aInfo = mService.getActivityInfoForUser(aInfo, userId);
}
}
}
}
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, inTask,
reason);
Binder.restoreCallingIdentity(origId);
if (stack.mConfigWillChange) {
// If the caller also wants to switch to a new configuration,
// do so now. This allows a clean switch, as we are waiting
// for the current activity to pause (so we will not destroy
// it), and have not yet started the next activity.
mService.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
"updateConfiguration()");
stack.mConfigWillChange = false;
if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
"Updating to new configuration after starting activity.");
mService.updateConfigurationLocked(globalConfig, null, false);
}
if (outResult != null) {
outResult.result = res;
if (res == ActivityManager.START_SUCCESS) {
mSupervisor.mWaitingActivityLaunched.add(outResult);
do {
try {
mService.wait();
} catch (InterruptedException e) {
}
} while (outResult.result != START_TASK_TO_FRONT
&& !outResult.timeout && outResult.who == null);
if (outResult.result == START_TASK_TO_FRONT) {
res = START_TASK_TO_FRONT;
}
}
if (res == START_TASK_TO_FRONT) {
final ActivityRecord r = outRecord[0];
// ActivityRecord may represent a different activity, but it should not be in
// the resumed state.
if (r.nowVisible && r.state == RESUMED) {
outResult.timeout = false;
outResult.who = r.realActivity;
outResult.totalTime = 0;
outResult.thisTime = 0;
} else {
outResult.thisTime = SystemClock.uptimeMillis();
mSupervisor.waitActivityVisible(r.realActivity, outResult);
// Note: the timeout variable is not currently not ever set.
do {
try {
mService.wait();
} catch (InterruptedException e) {
}
} while (!outResult.timeout && outResult.who == null);
}
}
}
mSupervisor.mActivityMetricsLogger.notifyActivityLaunched(res, outRecord[0]);
return res;
}
}
这代代码是真够长的,看到了是不是想放弃了,别急。慢慢看,其实这个方法里面的干货也很多,来总结一下:
好了那么我们就看关键的点:startActivityLocked();
int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,
aInfo, rInfo, voiceSession, voiceInteractor,
resultTo, resultWho, requestCode, callingPid,
callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
options, ignoreTargetSecurity, componentSpecified, outRecord, inTask,
reason);
具体看方法调用:
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, TaskRecord inTask, String reason) {
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);
if (outActivity != null) {
// mLastStartActivityRecord[0] is set in the call to startActivity above.
outActivity[0] = mLastStartActivityRecord[0];
}
// Aborted results are treated as successes externally, but we must track them internally.
return mLastStartActivityResult != START_ABORTED ? mLastStartActivityResult : START_SUCCESS;
}
实际调用了ActivityStarter的startActivity 我们来具体看看方法实现:
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.
if (!ActivityManager.isStartResultSuccessful(result)
&& mStartActivity.getTask() != null) {
mStartActivity.getTask().removeActivity(mStartActivity);
}
mService.mWindowManager.continueSurfaceLayout();
}
postStartActivityProcessing(r, result, mSupervisor.getLastStack().mStackId, mSourceRecord,
mTargetStack);
return result;
}
我们还是关系下主流程 其中又调用了startActivityUnchecked
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
ActivityRecord[] outActivity) {
setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
voiceInteractor);
computeLaunchingTaskFlags();
computeSourceStack();
mIntent.setFlags(mLaunchFlags);
ActivityRecord reusedActivity = getReusableIntentActivity();
final int preferredLaunchStackId =
(mOptions != null) ? mOptions.getLaunchStackId() : INVALID_STACK_ID;
final int preferredLaunchDisplayId =
(mOptions != null) ? mOptions.getLaunchDisplayId() : DEFAULT_DISPLAY;
if (reusedActivity != null) {
// When the flags NEW_TASK and CLEAR_TASK are set, then the task gets reused but
// still needs to be a lock task mode violation since the task gets cleared out and
// the device would otherwise leave the locked task.
if (mSupervisor.isLockTaskModeViolation(reusedActivity.getTask(),
(mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
== (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))) {
mSupervisor.showLockTaskToast();
Slog.e(TAG, "startActivityUnchecked: Attempt to violate Lock Task Mode");
return START_RETURN_LOCK_TASK_MODE_VIOLATION;
}
if (mStartActivity.getTask() == null) {
mStartActivity.setTask(reusedActivity.getTask());
}
if (reusedActivity.getTask().intent == null) {
// This task was started because of movement of the activity based on affinity...
// Now that we are actually launching it, we can assign the base intent.
reusedActivity.getTask().setIntent(mStartActivity);
}
// This code path leads to delivering a new intent, we want to make sure we schedule it
// as the first operation, in case the activity will be resumed as a result of later
// operations.
if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
|| isDocumentLaunchesIntoExisting(mLaunchFlags)
|| mLaunchSingleInstance || mLaunchSingleTask) {
final TaskRecord task = reusedActivity.getTask();
// In this situation we want to remove all activities from the task up to the one
// being started. In most cases this means we are resetting the task to its initial
// state.
final ActivityRecord top = task.performClearTaskForReuseLocked(mStartActivity,
mLaunchFlags);
// The above code can remove {@code reusedActivity} from the task, leading to the
// the {@code ActivityRecord} removing its reference to the {@code TaskRecord}. The
// task reference is needed in the call below to
// {@link setTargetStackAndMoveToFrontIfNeeded}.
if (reusedActivity.getTask() == null) {
reusedActivity.setTask(task);
}
if (top != null) {
if (top.frontOfTask) {
// Activity aliases may mean we use different intents for the top activity,
// so make sure the task now has the identity of the new intent.
top.getTask().setIntent(mStartActivity);
}
deliverNewIntent(top);
}
}
sendPowerHintForLaunchStartIfNeeded(false /* forceSend */, reusedActivity);
reusedActivity = setTargetStackAndMoveToFrontIfNeeded(reusedActivity);
final ActivityRecord outResult =
outActivity != null && outActivity.length > 0 ? outActivity[0] : null;
// When there is a reused activity and the current result is a trampoline activity,
// set the reused activity as the result.
if (outResult != null && (outResult.finishing || outResult.noDisplay)) {
outActivity[0] = reusedActivity;
}
if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
// We don't need to start a new activity, and the client said not to do anything
// if that is the case, so this is it! And for paranoia, make sure we have
// correctly resumed the top activity.
resumeTargetStackIfNeeded();
return START_RETURN_INTENT_TO_CALLER;
}
setTaskFromIntentActivity(reusedActivity);
if (!mAddingToTask && mReuseTask == null) {
// We didn't do anything... but it was needed (a.k.a., client don't use that
// intent!) And for paranoia, make sure we have correctly resumed the top activity.
resumeTargetStackIfNeeded();
if (outActivity != null && outActivity.length > 0) {
outActivity[0] = reusedActivity;
}
return START_TASK_TO_FRONT;
}
}
if (mStartActivity.packageName == null) {
final ActivityStack sourceStack = mStartActivity.resultTo != null
? mStartActivity.resultTo.getStack() : null;
if (sourceStack != null) {
sourceStack.sendActivityResultLocked(-1 /* callingUid */, mStartActivity.resultTo,
mStartActivity.resultWho, mStartActivity.requestCode, RESULT_CANCELED,
null /* data */);
}
ActivityOptions.abort(mOptions);
return START_CLASS_NOT_FOUND;
}
// If the activity being launched is the same as the one currently at the top, then
// we need to check if it should only be launched once.
final ActivityStack topStack = mSupervisor.mFocusedStack;
final ActivityRecord topFocused = topStack.topActivity();
final ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(mNotTop);
final boolean dontStart = top != null && mStartActivity.resultTo == null
&& top.realActivity.equals(mStartActivity.realActivity)
&& top.userId == mStartActivity.userId
&& top.app != null && top.app.thread != null
&& ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
|| mLaunchSingleTop || mLaunchSingleTask);
if (dontStart) {
// For paranoia, make sure we have correctly resumed the top activity.
topStack.mLastPausedActivity = null;
if (mDoResume) {
mSupervisor.resumeFocusedStackTopActivityLocked();
}
ActivityOptions.abort(mOptions);
if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
// We don't need to start a new activity, and the client said not to do
// anything if that is the case, so this is it!
return START_RETURN_INTENT_TO_CALLER;
}
deliverNewIntent(top);
// Don't use mStartActivity.task to show the toast. We're not starting a new activity
// but reusing 'top'. Fields in mStartActivity may not be fully initialized.
mSupervisor.handleNonResizableTaskIfNeeded(top.getTask(), preferredLaunchStackId,
preferredLaunchDisplayId, topStack.mStackId);
return START_DELIVERED_TO_TOP;
}
boolean newTask = false;
final TaskRecord taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
? mSourceRecord.getTask() : null;
// Should this be considered a new task?
int result = START_SUCCESS;
if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
&& (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
newTask = true;
result = setTaskFromReuseOrCreateNewTask(
taskToAffiliate, preferredLaunchStackId, topStack);
} else if (mSourceRecord != null) {
result = setTaskFromSourceRecord();
} else if (mInTask != null) {
result = setTaskFromInTask();
} else {
// This not being started from an existing activity, and not part of a new task...
// just put it in the top task, though these days this case should never happen.
setTaskToCurrentTopOrCreateNewTask();
}
if (result != START_SUCCESS) {
return result;
}
mService.grantUriPermissionFromIntentLocked(mCallingUid, mStartActivity.packageName,
mIntent, mStartActivity.getUriPermissionsLocked(), mStartActivity.userId);
mService.grantEphemeralAccessLocked(mStartActivity.userId, mIntent,
mStartActivity.appInfo.uid, UserHandle.getAppId(mCallingUid));
if (mSourceRecord != null) {
mStartActivity.getTask().setTaskToReturnTo(mSourceRecord);
}
if (newTask) {
EventLog.writeEvent(
EventLogTags.AM_CREATE_TASK, mStartActivity.userId,
mStartActivity.getTask().taskId);
}
ActivityStack.logStartActivity(
EventLogTags.AM_CREATE_ACTIVITY, mStartActivity, mStartActivity.getTask());
mTargetStack.mLastPausedActivity = null;
sendPowerHintForLaunchStartIfNeeded(false /* forceSend */, mStartActivity);
mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,
mOptions);
if (mDoResume) {
final ActivityRecord topTaskActivity =
mStartActivity.getTask().topRunningActivityLocked();
if (!mTargetStack.isFocusable()
|| (topTaskActivity != null && topTaskActivity.mTaskOverlay
&& mStartActivity != topTaskActivity)) {
// If the activity is not focusable, we can't resume it, but still would like to
// make sure it becomes visible as it starts (this will also trigger entry
// animation). An example of this are PIP activities.
// Also, we don't want to resume activities in a task that currently has an overlay
// as the starting activity just needs to be in the visible paused state until the
// over is removed.
mTargetStack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
// Go ahead and tell window manager to execute app transition for this activity
// since the app transition will not be triggered through the resume channel.
mWindowManager.executeAppTransition();
} else {
// If the target stack was not previously focusable (previous top running activity
// on that stack was not visible) then any prior calls to move the stack to the
// will not update the focused stack. If starting the new activity now allows the
// task stack to be focusable, then ensure that we now update the focused stack
// accordingly.
if (mTargetStack.isFocusable() && !mSupervisor.isFocusedStack(mTargetStack)) {
mTargetStack.moveToFront("startActivityUnchecked");
}
mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
mOptions);
}
} else {
mTargetStack.addRecentActivityLocked(mStartActivity);
}
mSupervisor.updateUserStackLocked(mStartActivity.userId, mTargetStack);
mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.getTask(), preferredLaunchStackId,
preferredLaunchDisplayId, mTargetStack.mStackId);
return START_SUCCESS;
}
这里摘要别人的总结:首先setInitialState()、computeLaunchingTaskFlags()、computeSourceStack()验证是否是特定的FLAG,后面执行了不同启动模式下的不同栈的处理。这些处理中关键的方法是mSupervisor.resumeFocusedStackTopActivityLocked() 其中 mSupervisor是该类的成员变量: ActivityStackSupervisor mSupervisor;
我们看下这个ActivityStackSupervisor 又是个什么?
我们看下这个 方法的具体实现mSupervisor.resumeFocusedStackTopActivityLocked()
boolean resumeFocusedStackTopActivityLocked() {
return resumeFocusedStackTopActivityLocked(null, null, null);
}
boolean resumeFocusedStackTopActivityLocked(
ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
...
mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
...
return false;
}
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
...
result = resumeTopActivityInnerLocked(prev, options);
...
return result;
}
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
...
mStackSupervisor.startSpecificActivityLocked(next, true, true);
...
}
void startSpecificActivityLocked(ActivityRecord r,
boolean andResume, boolean checkConfig) {
...
realStartActivityLocked(r, app, andResume, checkConfig);
...
}
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
boolean andResume, boolean checkConfig) throws RemoteException {
...
app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
System.identityHashCode(r), r.info,
// TODO: Have this take the merged configuration instead of separate global and
// override configs.
mergedConfiguration.getGlobalConfiguration(),
mergedConfiguration.getOverrideConfiguration(), r.compat,
r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
r.persistentState, results, newIntents, !andResume,
mService.isNextTransitionForward(), profilerInfo);
我们看下最后 app.thread.scheduleLaunchActivity(.........)这个方法,这个方法参数有点多,thread是IApplicationThread类型,ApplicationThread继承了IApplicationThread.Stub,因此app.thread是一个IApplicationThread的代理对象。和IActivityManager一样,app.thread调用scheduleLaunchActivity方法,通过Binder机制,会使ApplicationThread的scheduleLaunchActivity方法被调用。由此实现了第二次的进程间的通信,将启动Activity的操作交还给了ApplicationThread类。
又回到了我们熟悉的ActivityThread里了,ApplicationThread是ActivityThread的内部类,因此ApplicationThread可以调用外部类ActivityThread的方法,也就是说,启动Activity的操作交给了ActivityThread来处理。
private class ApplicationThread extends IApplicationThread.Stub {
..........//代理类
scheduleLaunchActivity();
}
我们要看下这个方法具体作了什么?scheduleLauchActivty();
// we use token to identify this activity without having to send the
749 // activity itself back to the activity manager. (matters more with ipc)
750 @Override
751 public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
752 ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
753 CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
754 int procState, Bundle state, PersistableBundle persistentState,
755 List pendingResults, List pendingNewIntents,
756 boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {
757
758 updateProcessState(procState, false);
759
760 ActivityClientRecord r = new ActivityClientRecord();
761
762 r.token = token;
763 r.ident = ident;
764 r.intent = intent;
765 r.referrer = referrer;
766 r.voiceInteractor = voiceInteractor;
767 r.activityInfo = info;
768 r.compatInfo = compatInfo;
769 r.state = state;
770 r.persistentState = persistentState;
771
772 r.pendingResults = pendingResults;
773 r.pendingIntents = pendingNewIntents;
774
775 r.startsNotResumed = notResumed;
776 r.isForward = isForward;
777
778 r.profilerInfo = profilerInfo;
779
780 r.overrideConfig = overrideConfig;
781 updatePendingConfiguration(curConfig);
782
783 sendMessage(H.LAUNCH_ACTIVITY, r);
784 }
看到这个783行,或许我们就明白了 sendMessage(H.LAUNCH_ACTIVITY, r);在ActivityThread中有个 H内部类,我们上代码看看都有什么?先看下sendMessage();里面具体实现
private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
2645 if (DEBUG_MESSAGES) Slog.v(
2646 TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
2647 + ": " + arg1 + " / " + obj);
2648 Message msg = Message.obtain();
2649 msg.what = what;
2650 msg.obj = obj;
2651 msg.arg1 = arg1;
2652 msg.arg2 = arg2;
2653 if (async) {
2654 msg.setAsynchronous(true);
2655 }
2656 mH.sendMessage(msg);
2657 }
private class H extends Handler {
1463
1521
1522 String codeToString(int code) {
1523 if (DEBUG_MESSAGES) {
1524 switch (code) {
1525 case LAUNCH_ACTIVITY: return "LAUNCH_ACTIVITY";
1526 case PAUSE_ACTIVITY: return "PAUSE_ACTIVITY";
1527 case PAUSE_ACTIVITY_FINISHING: return "PAUSE_ACTIVITY_FINISHING";
1528 case STOP_ACTIVITY_SHOW: return "STOP_ACTIVITY_SHOW";
1529 case STOP_ACTIVITY_HIDE: return "STOP_ACTIVITY_HIDE";
1530 case SHOW_WINDOW: return "SHOW_WINDOW";
1531 case HIDE_WINDOW: return "HIDE_WINDOW";
1532 case RESUME_ACTIVITY: return "RESUME_ACTIVITY";
1533 case SEND_RESULT: return "SEND_RESULT";
1534 case DESTROY_ACTIVITY: return "DESTROY_ACTIVITY";
1535 case BIND_APPLICATION: return "BIND_APPLICATION";
1536 case EXIT_APPLICATION: return "EXIT_APPLICATION";
1537 case NEW_INTENT: return "NEW_INTENT";
1538 case RECEIVER: return "RECEIVER";
1539 case CREATE_SERVICE: return "CREATE_SERVICE";
1540 case SERVICE_ARGS: return "SERVICE_ARGS";
1541 case STOP_SERVICE: return "STOP_SERVICE";
1542 case CONFIGURATION_CHANGED: return "CONFIGURATION_CHANGED";
1543 case CLEAN_UP_CONTEXT: return "CLEAN_UP_CONTEXT";
1544 case GC_WHEN_IDLE: return "GC_WHEN_IDLE";
1545 case BIND_SERVICE: return "BIND_SERVICE";
1546 case UNBIND_SERVICE: return "UNBIND_SERVICE";
1547 case DUMP_SERVICE: return "DUMP_SERVICE";
1548 case LOW_MEMORY: return "LOW_MEMORY";
1549 case ACTIVITY_CONFIGURATION_CHANGED: return "ACTIVITY_CONFIGURATION_CHANGED";
1550 case ACTIVITY_MOVED_TO_DISPLAY: return "ACTIVITY_MOVED_TO_DISPLAY";
1551 case RELAUNCH_ACTIVITY: return "RELAUNCH_ACTIVITY";
1552 case PROFILER_CONTROL: return "PROFILER_CONTROL";
1553 case CREATE_BACKUP_AGENT: return "CREATE_BACKUP_AGENT";
1554 case DESTROY_BACKUP_AGENT: return "DESTROY_BACKUP_AGENT";
1555 case SUICIDE: return "SUICIDE";
1556 case REMOVE_PROVIDER: return "REMOVE_PROVIDER";
1557 case ENABLE_JIT: return "ENABLE_JIT";
1558 case DISPATCH_PACKAGE_BROADCAST: return "DISPATCH_PACKAGE_BROADCAST";
1559 case SCHEDULE_CRASH: return "SCHEDULE_CRASH";
1560 case DUMP_HEAP: return "DUMP_HEAP";
1561 case DUMP_ACTIVITY: return "DUMP_ACTIVITY";
1562 case SLEEPING: return "SLEEPING";
1563 case SET_CORE_SETTINGS: return "SET_CORE_SETTINGS";
1564 case UPDATE_PACKAGE_COMPATIBILITY_INFO: return "UPDATE_PACKAGE_COMPATIBILITY_INFO";
1565 case TRIM_MEMORY: return "TRIM_MEMORY";
1566 case DUMP_PROVIDER: return "DUMP_PROVIDER";
1567 case UNSTABLE_PROVIDER_DIED: return "UNSTABLE_PROVIDER_DIED";
1568 case REQUEST_ASSIST_CONTEXT_EXTRAS: return "REQUEST_ASSIST_CONTEXT_EXTRAS";
1569 case TRANSLUCENT_CONVERSION_COMPLETE: return "TRANSLUCENT_CONVERSION_COMPLETE";
1570 case INSTALL_PROVIDER: return "INSTALL_PROVIDER";
1571 case ON_NEW_ACTIVITY_OPTIONS: return "ON_NEW_ACTIVITY_OPTIONS";
1572 case CANCEL_VISIBLE_BEHIND: return "CANCEL_VISIBLE_BEHIND";
1573 case BACKGROUND_VISIBLE_BEHIND_CHANGED: return "BACKGROUND_VISIBLE_BEHIND_CHANGED";
1574 case ENTER_ANIMATION_COMPLETE: return "ENTER_ANIMATION_COMPLETE";
1575 case MULTI_WINDOW_MODE_CHANGED: return "MULTI_WINDOW_MODE_CHANGED";
1576 case PICTURE_IN_PICTURE_MODE_CHANGED: return "PICTURE_IN_PICTURE_MODE_CHANGED";
1577 case LOCAL_VOICE_INTERACTION_STARTED: return "LOCAL_VOICE_INTERACTION_STARTED";
1578 case ATTACH_AGENT: return "ATTACH_AGENT";
1579 case APPLICATION_INFO_CHANGED: return "APPLICATION_INFO_CHANGED";
1580 }
1581 }
1582 return Integer.toString(code);
1583 }
1584 public void handleMessage(Message msg) {
1585 if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
1586 switch (msg.what) {
1587 case LAUNCH_ACTIVITY: {
1588 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
1589 final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
1590
1591 r.packageInfo = getPackageInfoNoCheck(
1592 r.activityInfo.applicationInfo, r.compatInfo);
1593 handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
1594 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1595 } break;
1596 case RELAUNCH_ACTIVITY: {
1597 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart");
1598 ActivityClientRecord r = (ActivityClientRecord)msg.obj;
1599 handleRelaunchActivity(r);
1600 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1601 } break;
1602 case PAUSE_ACTIVITY: {
1603 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
1604 SomeArgs args = (SomeArgs) msg.obj;
1605 handlePauseActivity((IBinder) args.arg1, false,
1606 (args.argi1 & USER_LEAVING) != 0, args.argi2,
1607 (args.argi1 & DONT_REPORT) != 0, args.argi3);
1608 maybeSnapshot();
1609 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1610 } break;
1611 case PAUSE_ACTIVITY_FINISHING: {
1612 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
1613 SomeArgs args = (SomeArgs) msg.obj;
1614 handlePauseActivity((IBinder) args.arg1, true, (args.argi1 & USER_LEAVING) != 0,
1615 args.argi2, (args.argi1 & DONT_REPORT) != 0, args.argi3);
1616 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1617 } break;
1618 case STOP_ACTIVITY_SHOW: {
1619 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStop");
1620 SomeArgs args = (SomeArgs) msg.obj;
1621 handleStopActivity((IBinder) args.arg1, true, args.argi2, args.argi3);
1622 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1623 } break;
1624 case STOP_ACTIVITY_HIDE: {
1625 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStop");
1626 SomeArgs args = (SomeArgs) msg.obj;
1627 handleStopActivity((IBinder) args.arg1, false, args.argi2, args.argi3);
1628 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1629 } break;
1630 case SHOW_WINDOW:
1631 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityShowWindow");
1632 handleWindowVisibility((IBinder)msg.obj, true);
1633 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1634 break;
1635 case HIDE_WINDOW:
1636 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityHideWindow");
1637 handleWindowVisibility((IBinder)msg.obj, false);
1638 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1639 break;
1640 case RESUME_ACTIVITY:
1641 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityResume");
1642 SomeArgs args = (SomeArgs) msg.obj;
1643 handleResumeActivity((IBinder) args.arg1, true, args.argi1 != 0, true,
1644 args.argi3, "RESUME_ACTIVITY");
1645 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1646 break;
1647 case SEND_RESULT:
1648 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityDeliverResult");
1649 handleSendResult((ResultData)msg.obj);
1650 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1651 break;
1652 case DESTROY_ACTIVITY:
1653 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityDestroy");
1654 handleDestroyActivity((IBinder)msg.obj, msg.arg1 != 0,
1655 msg.arg2, false);
1656 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1657 break;
1658 case BIND_APPLICATION:
1659 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
1660 AppBindData data = (AppBindData)msg.obj;
1661 handleBindApplication(data);
1662 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1663 break;
1664 case EXIT_APPLICATION:
1665 if (mInitialApplication != null) {
1666 mInitialApplication.onTerminate();
1667 }
1668 Looper.myLooper().quit();
1669 break;
1670 case NEW_INTENT:
1671 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityNewIntent");
1672 handleNewIntent((NewIntentData)msg.obj);
1673 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1674 break;
1675 case RECEIVER:
1676 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveComp");
1677 handleReceiver((ReceiverData)msg.obj);
1678 maybeSnapshot();
1679 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1680 break;
1681 case CREATE_SERVICE:
1682 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceCreate: " + String.valueOf(msg.obj)));
1683 handleCreateService((CreateServiceData)msg.obj);
1684 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1685 break;
1686 case BIND_SERVICE:
1687 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind");
1688 handleBindService((BindServiceData)msg.obj);
1689 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1690 break;
1691 case UNBIND_SERVICE:
1692 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceUnbind");
1693 handleUnbindService((BindServiceData)msg.obj);
1694 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1695 break;
1696 case SERVICE_ARGS:
1697 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceStart: " + String.valueOf(msg.obj)));
1698 handleServiceArgs((ServiceArgsData)msg.obj);
1699 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1700 break;
1701 case STOP_SERVICE:
1702 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStop");
1703 handleStopService((IBinder)msg.obj);
1704 maybeSnapshot();
1705 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1706 break;
1707 case CONFIGURATION_CHANGED:
1708 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "configChanged");
1709 mCurDefaultDisplayDpi = ((Configuration)msg.obj).densityDpi;
1710 mUpdatingSystemConfig = true;
1711 try {
1712 handleConfigurationChanged((Configuration) msg.obj, null);
1713 } finally {
1714 mUpdatingSystemConfig = false;
1715 }
1716 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1717 break;
1718 case CLEAN_UP_CONTEXT:
1719 ContextCleanupInfo cci = (ContextCleanupInfo)msg.obj;
1720 cci.context.performFinalCleanup(cci.who, cci.what);
1721 break;
1722 case GC_WHEN_IDLE:
1723 scheduleGcIdler();
1724 break;
1725 case DUMP_SERVICE:
1726 handleDumpService((DumpComponentInfo)msg.obj);
1727 break;
1728 case LOW_MEMORY:
1729 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "lowMemory");
1730 handleLowMemory();
1731 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1732 break;
1733 case ACTIVITY_CONFIGURATION_CHANGED:
1734 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityConfigChanged");
1735 handleActivityConfigurationChanged((ActivityConfigChangeData) msg.obj,
1736 INVALID_DISPLAY);
1737 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1738 break;
1739 case ACTIVITY_MOVED_TO_DISPLAY:
1740 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityMovedToDisplay");
1741 handleActivityConfigurationChanged((ActivityConfigChangeData) msg.obj,
1742 msg.arg1 /* displayId */);
1743 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1744 break;
1745 case PROFILER_CONTROL:
1746 handleProfilerControl(msg.arg1 != 0, (ProfilerInfo)msg.obj, msg.arg2);
1747 break;
1748 case CREATE_BACKUP_AGENT:
1749 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backupCreateAgent");
1750 handleCreateBackupAgent((CreateBackupAgentData)msg.obj);
1751 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1752 break;
1753 case DESTROY_BACKUP_AGENT:
1754 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backupDestroyAgent");
1755 handleDestroyBackupAgent((CreateBackupAgentData)msg.obj);
1756 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1757 break;
1758 case SUICIDE:
1759 Process.killProcess(Process.myPid());
1760 break;
1761 case REMOVE_PROVIDER:
1762 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "providerRemove");
1763 completeRemoveProvider((ProviderRefCount)msg.obj);
1764 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1765 break;
1766 case ENABLE_JIT:
1767 ensureJitEnabled();
1768 break;
1769 case DISPATCH_PACKAGE_BROADCAST:
1770 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastPackage");
1771 handleDispatchPackageBroadcast(msg.arg1, (String[])msg.obj);
1772 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1773 break;
1774 case SCHEDULE_CRASH:
1775 throw new RemoteServiceException((String)msg.obj);
1776 case DUMP_HEAP:
1777 handleDumpHeap(msg.arg1 != 0, (DumpHeapData)msg.obj);
1778 break;
1779 case DUMP_ACTIVITY:
1780 handleDumpActivity((DumpComponentInfo)msg.obj);
1781 break;
1782 case DUMP_PROVIDER:
1783 handleDumpProvider((DumpComponentInfo)msg.obj);
1784 break;
1785 case SLEEPING:
1786 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "sleeping");
1787 handleSleeping((IBinder)msg.obj, msg.arg1 != 0);
1788 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1789 break;
1790 case SET_CORE_SETTINGS:
1791 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "setCoreSettings");
1792 handleSetCoreSettings((Bundle) msg.obj);
1793 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1794 break;
1795 case UPDATE_PACKAGE_COMPATIBILITY_INFO:
1796 handleUpdatePackageCompatibilityInfo((UpdateCompatibilityData)msg.obj);
1797 break;
1798 case TRIM_MEMORY:
1799 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "trimMemory");
1800 handleTrimMemory(msg.arg1);
1801 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1802 break;
1803 case UNSTABLE_PROVIDER_DIED:
1804 handleUnstableProviderDied((IBinder)msg.obj, false);
1805 break;
1806 case REQUEST_ASSIST_CONTEXT_EXTRAS:
1807 handleRequestAssistContextExtras((RequestAssistContextExtras)msg.obj);
1808 break;
1809 case TRANSLUCENT_CONVERSION_COMPLETE:
1810 handleTranslucentConversionComplete((IBinder)msg.obj, msg.arg1 == 1);
1811 break;
1812 case INSTALL_PROVIDER:
1813 handleInstallProvider((ProviderInfo) msg.obj);
1814 break;
1815 case ON_NEW_ACTIVITY_OPTIONS:
1816 Pair pair = (Pair) msg.obj;
1817 onNewActivityOptions(pair.first, pair.second);
1818 break;
1819 case CANCEL_VISIBLE_BEHIND:
1820 handleCancelVisibleBehind((IBinder) msg.obj);
1821 break;
1822 case BACKGROUND_VISIBLE_BEHIND_CHANGED:
1823 handleOnBackgroundVisibleBehindChanged((IBinder) msg.obj, msg.arg1 > 0);
1824 break;
1825 case ENTER_ANIMATION_COMPLETE:
1826 handleEnterAnimationComplete((IBinder) msg.obj);
1827 break;
1828 case START_BINDER_TRACKING:
1829 handleStartBinderTracking();
1830 break;
1831 case STOP_BINDER_TRACKING_AND_DUMP:
1832 handleStopBinderTrackingAndDump((ParcelFileDescriptor) msg.obj);
1833 break;
1834 case MULTI_WINDOW_MODE_CHANGED:
1835 handleMultiWindowModeChanged((IBinder) ((SomeArgs) msg.obj).arg1,
1836 ((SomeArgs) msg.obj).argi1 == 1,
1837 (Configuration) ((SomeArgs) msg.obj).arg2);
1838 break;
1839 case PICTURE_IN_PICTURE_MODE_CHANGED:
1840 handlePictureInPictureModeChanged((IBinder) ((SomeArgs) msg.obj).arg1,
1841 ((SomeArgs) msg.obj).argi1 == 1,
1842 (Configuration) ((SomeArgs) msg.obj).arg2);
1843 break;
1844 case LOCAL_VOICE_INTERACTION_STARTED:
1845 handleLocalVoiceInteractionStarted((IBinder) ((SomeArgs) msg.obj).arg1,
1846 (IVoiceInteractor) ((SomeArgs) msg.obj).arg2);
1847 break;
1848 case ATTACH_AGENT:
1849 handleAttachAgent((String) msg.obj);
1850 break;
1851 case APPLICATION_INFO_CHANGED:
1852 mUpdatingSystemConfig = true;
1853 try {
1854 handleApplicationInfoChanged((ApplicationInfo) msg.obj);
1855 } finally {
1856 mUpdatingSystemConfig = false;
1857 }
1858 break;
1859 }
1860
1865 }
源码有点长,我们就看启动这个case吧
case LAUNCH_ACTIVITY: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
r.packageInfo = getPackageInfoNoCheck(
r.activityInfo.applicationInfo, r.compatInfo);
handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
调用ActivityThread的handleLaunchActivity方法启动Activity,源码如下:
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
2873 // If we are getting ready to gc after going to the background, well
2874 // we are back active so skip it.
2875 unscheduleGcIdler();
2876 mSomeActivitiesChanged = true;
2877
2878 if (r.profilerInfo != null) {
2879 mProfiler.setProfiler(r.profilerInfo);
2880 mProfiler.startProfiling();
2881 }
2882
2883 // Make sure we are running with the most recent config.
2884 handleConfigurationChanged(null, null);
2885
2886 if (localLOGV) Slog.v(
2887 TAG, "Handling launch of " + r);
2888
2889 // Initialize before creating the activity
2890 WindowManagerGlobal.initialize();
2891
2892 Activity a = performLaunchActivity(r, customIntent);
2893
2894 if (a != null) {
2895 r.createdConfig = new Configuration(mConfiguration);
2896 reportSizeConfigurations(r);
2897 Bundle oldState = r.state;
2898 handleResumeActivity(r.token, false, r.isForward,
2899 !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
2900
2901 if (!r.activity.mFinished && r.startsNotResumed) {
2902 // The activity manager actually wants this one to start out paused, because it
2903 // needs to be visible but isn't in the foreground. We accomplish this by going
2904 // through the normal startup (because activities expect to go through onResume()
2905 // the first time they run, before their window is displayed), and then pausing it.
2906 // However, in this case we do -not- need to do the full pause cycle (of freezing
2907 // and such) because the activity manager assumes it can just retain the current
2908 // state it has.
2909 performPauseActivityIfNeeded(r, reason);
2910
2911 // We need to keep around the original state, in case we need to be created again.
2912 // But we only do this for pre-Honeycomb apps, which always save their state when
2913 // pausing, so we can not have them save their state when restarting from a paused
2914 // state. For HC and later, we want to (and can) let the state be saved as the
2915 // normal part of stopping the activity.
2916 if (r.isPreHoneycomb()) {
2917 r.state = oldState;
2918 }
2919 }
2920 } else {
2921 // If there was an error, for any reason, tell the activity manager to stop us.
2922 try {
2923 ActivityManager.getService()
2924 .finishActivity(r.token, Activity.RESULT_CANCELED, null,
2925 Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
2926 } catch (RemoteException ex) {
2927 throw ex.rethrowFromSystemServer();
2928 }
2929 }
2930 }
关键代码 Activity a = performLaunchActivity(r, customIntent);来返回一个Activity,若Activity不为空,则调用handleResumeActivity方法,内部会调用Activity$onResume方法。当Activity为空,也就是创建Activity的实例出错了,最终会调用ActivityManagerService$finishActivity方法。也就是说,当创建Activity实例出错后,停止启动Activity的具体操作交给ActivityManagerService来处理。
我们来看下performLaunchActivity()这个方法
2683 private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
2684 // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");
2685
2686 ActivityInfo aInfo = r.activityInfo;
2687 if (r.packageInfo == null) {
2688 r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
2689 Context.CONTEXT_INCLUDE_CODE);
2690 }
2691
2692 ComponentName component = r.intent.getComponent();
2693 if (component == null) {
2694 component = r.intent.resolveActivity(
2695 mInitialApplication.getPackageManager());
2696 r.intent.setComponent(component);
2697 }
2698
2699 if (r.activityInfo.targetActivity != null) {
2700 component = new ComponentName(r.activityInfo.packageName,
2701 r.activityInfo.targetActivity);
2702 }
2703
2704 ContextImpl appContext = createBaseContextForActivity(r);
2705 Activity activity = null;
2706 try {
2707 java.lang.ClassLoader cl = appContext.getClassLoader();
2708 activity = mInstrumentation.newActivity(
2709 cl, component.getClassName(), r.intent);
2710 StrictMode.incrementExpectedActivityCount(activity.getClass());
2711 r.intent.setExtrasClassLoader(cl);
2712 r.intent.prepareToEnterProcess();
2713 if (r.state != null) {
2714 r.state.setClassLoader(cl);
2715 }
2716 } catch (Exception e) {
2717 if (!mInstrumentation.onException(activity, e)) {
2718 throw new RuntimeException(
2719 "Unable to instantiate activity " + component
2720 + ": " + e.toString(), e);
2721 }
2722 }
2723
2724 try {
2725 Application app = r.packageInfo.makeApplication(false, mInstrumentation);
2726
2727 if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
2728 if (localLOGV) Slog.v(
2729 TAG, r + ": app=" + app
2730 + ", appName=" + app.getPackageName()
2731 + ", pkg=" + r.packageInfo.getPackageName()
2732 + ", comp=" + r.intent.getComponent().toShortString()
2733 + ", dir=" + r.packageInfo.getAppDir());
2734
2735 if (activity != null) {
2736 CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
2737 Configuration config = new Configuration(mCompatConfiguration);
2738 if (r.overrideConfig != null) {
2739 config.updateFrom(r.overrideConfig);
2740 }
2741 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
2742 + r.activityInfo.name + " with config " + config);
2743 Window window = null;
2744 if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
2745 window = r.mPendingRemoveWindow;
2746 r.mPendingRemoveWindow = null;
2747 r.mPendingRemoveWindowManager = null;
2748 }
2749 appContext.setOuterContext(activity);
2750 activity.attach(appContext, this, getInstrumentation(), r.token,
2751 r.ident, app, r.intent, r.activityInfo, title, r.parent,
2752 r.embeddedID, r.lastNonConfigurationInstances, config,
2753 r.referrer, r.voiceInteractor, window, r.configCallback);
2754
2755 if (customIntent != null) {
2756 activity.mIntent = customIntent;
2757 }
2758 r.lastNonConfigurationInstances = null;
2759 checkAndBlockForNetworkAccess();
2760 activity.mStartedActivity = false;
2761 int theme = r.activityInfo.getThemeResource();
2762 if (theme != 0) {
2763 activity.setTheme(theme);
2764 }
2765
2766 activity.mCalled = false;
2767 if (r.isPersistable()) {
2768 mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
2769 } else {
2770 mInstrumentation.callActivityOnCreate(activity, r.state);
2771 }
2772 if (!activity.mCalled) {
2773 throw new SuperNotCalledException(
2774 "Activity " + r.intent.getComponent().toShortString() +
2775 " did not call through to super.onCreate()");
2776 }
2777 r.activity = activity;
2778 r.stopped = true;
2779 if (!r.activity.mFinished) {
2780 activity.performStart();
2781 r.stopped = false;
2782 }
2783 if (!r.activity.mFinished) {
2784 if (r.isPersistable()) {
2785 if (r.state != null || r.persistentState != null) {
2786 mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
2787 r.persistentState);
2788 }
2789 } else if (r.state != null) {
2790 mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
2791 }
2792 }
2793 if (!r.activity.mFinished) {
2794 activity.mCalled = false;
2795 if (r.isPersistable()) {
2796 mInstrumentation.callActivityOnPostCreate(activity, r.state,
2797 r.persistentState);
2798 } else {
2799 mInstrumentation.callActivityOnPostCreate(activity, r.state);
2800 }
2801 if (!activity.mCalled) {
2802 throw new SuperNotCalledException(
2803 "Activity " + r.intent.getComponent().toShortString() +
2804 " did not call through to super.onPostCreate()");
2805 }
2806 }
2807 }
2808 r.paused = true;
2809
2810 mActivities.put(r.token, r);
2811
2812 } catch (SuperNotCalledException e) {
2813 throw e;
2814
2815 } catch (Exception e) {
2816 if (!mInstrumentation.onException(activity, e)) {
2817 throw new RuntimeException(
2818 "Unable to start activity " + component
2819 + ": " + e.toString(), e);
2820 }
2821 }
2822
2823 return activity;
2824 }
是不是很长,我们看关键的代码:activity = mInstrumentation.newActivity( cl, component.getClassName(), r.intent); mInstrumentation这个又回到开篇第一个讲的类了 Instrumentation,忘记了的小伙伴可以再去看一下。
mInstrumentation.newActivity( cl, component.getClassName(), r.intent); 的源码如下:
public Activity newActivity(ClassLoader cl, String className,
Intent intent)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
return (Activity)cl.loadClass(className).newInstance();
}
Application app = r.loadedApk.makeApplication(false, mInstrumentation);
public Application makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation) {
if (mApplication != null) {
return mApplication;
}
Application app = null;
//...
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
//...
mApplication = app;
instrumentation.callApplicationOnCreate(app);
//...
return app;
}
获取要启动的Activity的ComponentName对象:里面包含了包名,类名相关的信息;调用newActivity方法,attach方法后启动Activity(调用Instrumentation$callActivityOnCreate方法)
终于到了最后的关键:创建Activity,创建Application,调用Attach,最后mInstrumentation.callActivityOnCreate(activity, r.state);
public void callActivityOnCreate(Activity activity, Bundle icicle) {
prePerformCreate(activity);
activity.performCreate(icicle);
postPerformCreate(activity);
}
final void performCreate(Bundle icicle) {
restoreHasCurrentPermissionRequest(icicle);
onCreate(icicle);
mActivityTransitionState.readState(icicle);
performCreateCommon();
}
本文完!