初探Activity启动流程--startActivity---android 30
- 1.前言
- 2.时序图
- 3.源码分析
- android.app.Activity.startActivity
- android.app.Instrumentation
- com.android.server.wm.ActivityTaskManagerService
- com.android.server.wm.ActivityStarter
- com.android.server.wm.RootWindowContainer
- com.android.server.wm.ActivityStack
- com.android.server.wm.ActivityStackSupervisor
- 从上面可以看到很多个ActivityItem,我分别在下面列举出来
- android.app.servertransaction.LaunchActivityItem extends ClientTransactionItem
- android.app.servertransaction.NewIntentItem extends ClientTransactionItem
- android.app.servertransaction.ActivityResultItem extends ClientTransactionItem
- android.app.servertransaction.ActivityLifecycleItem extends ClientTransactionItem-----抽象类
- android.app.servertransaction.ResumeActivityItem extends ActivityLifecycleItem
- android.app.servertransaction.PauseActivityItem extends ActivityLifecycleItem
- com.android.server.wm.ClientLifecycleManager
- android.app.servertransaction.ClientTransaction
- android.app.ClientTransactionHandler
- android.app.ActivityThread extends android.app.ClientTransactionHandler
- android.app.ContextImpl
- android.app.ActivityThread.ApplicationThread.H extend Handler
- android.app.servertransaction.TransactionExecutor
1.前言
以前看过很多别人写的Android启动流程,当然自己也跟着代码走过几遍,因为只是看看并没有做过任何到总结,所以到现在也类似没看,现在工作需要用到动态加载,所以想好好到梳理一遍,并且记录下来;
现在发现做笔记非常到重要,从大学开始到现在,我花了很多时间都在学习,看各种视频学各种语言,但是都没有以文档到形式,回顾过,记录过,所以如果有人问我学了什么,我只能说,我也不知道,所以同一个视频,我经常反复看,感觉真的很浪费时间,所以以我的亲身经历告诉大家,不要一直总是以学习(看视频,看书)的方式,也是需要输出的,不仅仅是代码的输出,文档的输出也是有必要的,当然如果能有时序图、类图、活动图等,当然是最好了,总结是真的很重要。
2.时序图
3.源码分析
android.app.Activity.startActivity
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);
}
...
}
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode, @Nullable Bundle options) {
...
Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
...
}
final void performResume(boolean followedByPause, String reason) {
...
// mResumed is set by the instrumentation
mInstrumentation.callActivityOnResume(this);
...
}
android.app.Instrumentation
> @UnsupportedAppUsage
public void execStartActivities(Context who, IBinder contextThread, IBinder token, Activity target, Intent[] intents, Bundle options)
execStartActivitiesAsUser(who, contextThread, token, target, intents, options,
who.getUserId());
}
public int execStartActivitiesAsUser(Context who, IBinder contextThread, IBinder token, Activity target, Intent[] intents, Bundle options, int userId) {
//这个要注意,在后面会用到
IApplicationThread whoThread = (IApplicationThread) contextThread;
String[] resolvedTypes = new String[intents.length];
for (int i=0; i<intents.length; i++) {
intents[i].migrateExtraStreamToClipData(who);
intents[i].prepareToLeaveProcess(who);
resolvedTypes[i] = intents[i].resolveTypeIfNeeded(who.getContentResolver());
}
int result = ActivityTaskManager.getService().startActivities(whoThread,
who.getBasePackageName(), who.getAttributionTag(), intents, resolvedTypes,
token, options, userId);
checkStartActivityResult(result, intents[0]);
return result;
.....
}
/**
* Perform instantiation of an {@link Activity} object. This method is intended for use with
* unit tests, such as android.test.ActivityUnitTestCase. The activity will be useable
* locally but will be missing some of the linkages necessary for use within the system.
*
* @param clazz The Class of the desired Activity
* @param context The base context for the activity to use
* @param token The token for this activity to communicate with
* @param application The application object (if any)
* @param intent The intent that started this Activity
* @param info ActivityInfo from the manifest
* @param title The title, typically retrieved from the ActivityInfo record
* @param parent The parent Activity (if any)
* @param id The embedded Id (if any)
* @param lastNonConfigurationInstance Arbitrary object that will be
* available via {@link Activity#getLastNonConfigurationInstance()
* Activity.getLastNonConfigurationInstance()}.
* @return Returns the instantiated activity
* @throws InstantiationException
* @throws IllegalAccessException
*/
//Activity的生成 -----这个在下面会调用
public Activity newActivity(Class<?> clazz, Context context,
IBinder token, Application application, Intent intent, ActivityInfo info,
CharSequence title, Activity parent, String id,
Object lastNonConfigurationInstance) throws InstantiationException,
IllegalAccessException {
Activity activity = (Activity)clazz.newInstance();
ActivityThread aThread = null;
// Activity.attach expects a non-null Application Object.
if (application == null) {
application = new Application();
}
activity.attach(context, aThread, this, token, 0 /* ident */, application, intent,
info, title, parent, id,
(Activity.NonConfigurationInstances)lastNonConfigurationInstance,
new Configuration(), null /* referrer */, null /* voiceInteractor */,
null /* window */, null /* activityConfigCallback */, null /*assistToken*/);
return activity;
}
/**
* Perform calling of an activity's {@link Activity#onResume} method. The
* default implementation simply calls through to that method.
*
* @param activity The activity being resumed.
*/
public void callActivityOnResume(Activity activity) {
activity.mResumed = true;
activity.onResume();
...
}
com.android.server.wm.ActivityTaskManagerService
public final int startActivity(IApplicationThread caller, String callingPackage,String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
return ***startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,
resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions,
UserHandle.getCallingUserId());***
}
private int startActivityAsUser(IApplicationThread caller, String callingPackage,@Nullable String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) {
assertPackageMatchesCallingUid(callingPackage);
enforceNotIsolatedCaller("startActivityAsUser");
...
// TODO: Switch to user app stacks here.
return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
.setCaller(caller)
.setCallingPackage(callingPackage)
.setCallingFeatureId(callingFeatureId)
.setResolvedType(resolvedType)
.setResultTo(resultTo)
.setResultWho(resultWho)
.setRequestCode(requestCode)
.setStartFlags(startFlags)
.setProfilerInfo(profilerInfo)
.setActivityOptions(bOptions)
.setUserId(userId)
.execute();***
}
com.android.server.wm.ActivityStarter
/**
* Resolve necessary information according the request parameters provided earlier, and execute
* the request which begin the journey of starting an activity.
* @return The starter result.
*/
int execute() {
...
res = executeRequest(mRequest);
...
}
private int executeRequest(Request request) {
....
mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
request.voiceInteractor, startFlags, true, checkedOptions, inTask,
restrictedBgActivity, intentGrants);
if (request.outActivity != null) {
request.outActivity[0] = mLastStartActivityRecord;
}
return mLastStartActivityResult;
}
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, boolean doResume, ActivityOptions options, Task inTask,boolean restrictedBgActivity, NeededUriGrants intentGrants) {
...
result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, doResume, options, inTask, restrictedBgActivity, intentGrants);
...
}
int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,int startFlags, boolean doResume, ActivityOptions options,
Task inTask, boolean restrictedBgActivity, NeededUriGrants intentGrants) {
...
mRootWindowContainer.resumeFocusedStacksTopActivities(
mTargetStack, mStartActivity, mOptions);
...
}
com.android.server.wm.RootWindowContainer
boolean resumeFocusedStacksTopActivities(
ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
if (!mStackSupervisor.readyToResume()) {
return false;
}
boolean result = false;
if (targetStack != null && (targetStack.isTopStackInDisplayArea()
|| getTopDisplayFocusedStack() == targetStack)) {
result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}
for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
boolean resumedOnDisplay = false;
final DisplayContent display = getChildAt(displayNdx);
for (int tdaNdx = display.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) {
final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tdaNdx);
for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) {
final ActivityStack stack = taskDisplayArea.getStackAt(sNdx);
final ActivityRecord topRunningActivity = stack.topRunningActivity();
if (!stack.isFocusableAndVisible() || topRunningActivity == null) {
continue;
}
if (stack == targetStack) {
// Simply update the result for targetStack because the targetStack had
// already resumed in above. We don't want to resume it again, especially in
// some cases, it would cause a second launch failure if app process was
// dead.
resumedOnDisplay |= result;
continue;
}
if (taskDisplayArea.isTopStack(stack) && topRunningActivity.isState(RESUMED)) {
// Kick off any lingering app transitions form the MoveTaskToFront
// operation, but only consider the top task and stack on that display.
stack.executeAppTransition(targetOptions);
} else {
resumedOnDisplay |= topRunningActivity.makeActiveIfNeeded(target);
}
}
}
if (!resumedOnDisplay) {
// In cases when there are no valid activities (e.g. device just booted or launcher
// crashed) it's possible that nothing was resumed on a display. Requesting resume
// of top activity in focused stack explicitly will make sure that at least home
// activity is started and resumed, and no recursion occurs.
final ActivityStack focusedStack = display.getFocusedStack();
if (focusedStack != null) {
result |= focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions);
} else if (targetStack == null) {
result |= resumeHomeActivity(null /* prev */, "no-focusable-task",
display.getDefaultTaskDisplayArea());
}
}
}
return result;
}
com.android.server.wm.ActivityStack
@GuardedBy("mService")
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
if (mInResumeTopActivity) {
// Don't even start recursing.
return false;
}
boolean result = false;
try {
// Protect against recursion.
mInResumeTopActivity = true;
result = resumeTopActivityInnerLocked(prev, options);
// When resuming the top activity, it may be necessary to pause the top activity (for
// example, returning to the lock screen. We suppress the normal pause logic in
// {@link #resumeTopActivityUncheckedLocked}, since the top activity is resumed at the
// end. We call the {@link ActivityStackSupervisor#checkReadyForSleepLocked} again here
// to ensure any necessary pause logic occurs. In the case where the Activity will be
// shown regardless of the lock screen, the call to
// {@link ActivityStackSupervisor#checkReadyForSleepLocked} is skipped.
final ActivityRecord next = topRunningActivity(true /* focusableOnly */);
if (next == null || !next.canTurnScreenOn()) {
checkReadyForSleep();
}
} finally {
mInResumeTopActivity = false;
}
return result;
}
@GuardedBy("mService")
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
...
try {
final ClientTransaction transaction =
ClientTransaction.obtain(next.app.getThread(), next.appToken);
// Deliver all pending results.
ArrayList<ResultInfo> a = next.results;
if (a != null) {
final int N = a.size();
if (!next.finishing && N > 0) {
if (DEBUG_RESULTS) Slog.v(TAG_RESULTS,
"Delivering results to " + next + ": " + a);
transaction.addCallback(ActivityResultItem.obtain(a));
}
}
if (next.newIntents != null) {
transaction.addCallback(
NewIntentItem.obtain(next.newIntents, true /* resume */));
}
// Well the app will no longer be stopped.
// Clear app token stopped state in window manager if needed.
next.notifyAppResumed(next.stopped);
EventLogTags.writeWmResumeActivity(next.mUserId, System.identityHashCode(next),
next.getTask().mTaskId, next.shortComponentName);
next.setSleeping(false);
mAtmService.getAppWarningsLocked().onResumeActivity(next);
next.app.setPendingUiCleanAndForceProcessStateUpTo(mAtmService.mTopProcessState);
next.clearOptionsLocked();
transaction.setLifecycleStateRequest(
ResumeActivityItem.obtain(next.app.getReportedProcState(),
dc.isNextTransitionForward()));
mAtmService.getLifecycleManager().scheduleTransaction(transaction);
...
}
com.android.server.wm.ActivityStackSupervisor
void startSpecificActivity(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);
}
// If a dead object exception was thrown -- fall through to
// restart the application.
knownToBeDead = true;
}
r.notifyUnknownVisibilityLaunchedForKeyguardTransition();
final boolean isTop = andResume && r.isTopRunningActivity();
mService.startProcessAsync(r, knownToBeDead, isTop, isTop ? "top-activity" : "activity");
}
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.getSavedState(), r.getPersistentSavedState(), results, newIntents,
dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
r.assistToken, r.createFixedRotationAdjustmentsIfNeeded()));
// 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);
...
}
从上面可以看到很多个ActivityItem,我分别在下面列举出来
android.app.servertransaction.LaunchActivityItem extends ClientTransactionItem
48 private Intent mIntent;
49 private int mIdent;
50 private ActivityInfo mInfo;
51 private Configuration mCurConfig;
52 private Configuration mOverrideConfig;
53 private CompatibilityInfo mCompatInfo;
54 private String mReferrer;
55 private IVoiceInteractor mVoiceInteractor;
56 private int mProcState;
57 private Bundle mState;
58 private PersistableBundle mPersistentState;
59 private List<ResultInfo> mPendingResults;
60 private List<ReferrerIntent> mPendingNewIntents;
61 private boolean mIsForward;
62 private ProfilerInfo mProfilerInfo;
63
64 @Override
65 public void preExecute(ClientTransactionHandler client, IBinder token) {
66 client.updateProcessState(mProcState, false);
67 client.updatePendingConfiguration(mCurConfig);
68 }
69
70 @Override
71 public void execute(ClientTransactionHandler client, IBinder token,
72 PendingTransactionActions pendingActions) {
73 Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
74 ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
75 mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
76 mPendingResults, mPendingNewIntents, mIsForward,
77 mProfilerInfo, client);
//这里转到下面的ActivityThread ,client代表的是ActivityThread对象
78 client.handleLaunchActivity(r, pendingActions, null /* customIntent */); ---->Activity.attach,Activity.onCreate
79 Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
80 }
android.app.servertransaction.NewIntentItem extends ClientTransactionItem
@Override
46 public void execute(ClientTransactionHandler client, IBinder token,
47 PendingTransactionActions pendingActions) {
48 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityNewIntent");
49 client.handleNewIntent(token, mIntents, mPause); ------> 最终会调用到Activity.onNewIntent
50 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
51 }
android.app.servertransaction.ActivityResultItem extends ClientTransactionItem
@Override
46 public void execute(ClientTransactionHandler client, IBinder token,
47 PendingTransactionActions pendingActions) {
48 Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityDeliverResult");
49 client.handleSendResult(token, mResultInfoList, "ACTIVITY_RESULT"); --->最终会调用到Activity.performPause
50 Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
51 }
52
android.app.servertransaction.ActivityLifecycleItem extends ClientTransactionItem-----抽象类
@IntDef(prefix = { "UNDEFINED", "PRE_", "ON_" }, value = {
31 UNDEFINED,
32 PRE_ON_CREATE,
33 ON_CREATE,
34 ON_START,
35 ON_RESUME,
36 ON_PAUSE,
37 ON_STOP,
38 ON_DESTROY,
39 ON_RESTART
40 })
41 @Retention(RetentionPolicy.SOURCE)
42 public @interface LifecycleState{}
43 public static final int UNDEFINED = -1;
44 public static final int PRE_ON_CREATE = 0;
45 public static final int ON_CREATE = 1;
46 public static final int ON_START = 2;
47 public static final int ON_RESUME = 3;
48 public static final int ON_PAUSE = 4;
49 public static final int ON_STOP = 5;
50 public static final int ON_DESTROY = 6;
51 public static final int ON_RESTART = 7;
android.app.servertransaction.ResumeActivityItem extends ActivityLifecycleItem
@Override
48 public void execute(ClientTransactionHandler client, IBinder token,
49 PendingTransactionActions pendingActions) {
50 Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityResume");
51 client.handleResumeActivity(token, true /* finalStateRequest */, mIsForward, ----Activity.onResume
52 "RESUME_ACTIVITY");
53 Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
54 }
55
56 @Override
57 public void postExecute(ClientTransactionHandler client, IBinder token,
58 PendingTransactionActions pendingActions) {
59 try {
60 // TODO(lifecycler): Use interface callback instead of AMS.
61 ActivityManager.getService().activityResumed(token);
62 } catch (RemoteException ex) {
63 throw ex.rethrowFromSystemServer();
64 }
65 }
66
67 @Override
68 public int getTargetState() {
69 return ON_RESUME;
70 }
android.app.servertransaction.PauseActivityItem extends ActivityLifecycleItem
36 private boolean mFinished;
37 private boolean mUserLeaving;
38 private int mConfigChanges;
39 private boolean mDontReport;
40
41 @Override
42 public void execute(ClientTransactionHandler client, IBinder token,
43 PendingTransactionActions pendingActions) {
44 Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
45 client.handlePauseActivity(token, mFinished, mUserLeaving, mConfigChanges, pendingActions,
46 "PAUSE_ACTIVITY_ITEM");
47 Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
48 }
49
50 @Override
51 public int getTargetState() {
52 return ON_PAUSE;
53 }
54
55 @Override
56 public void postExecute(ClientTransactionHandler client, IBinder token,
57 PendingTransactionActions pendingActions) {
58 if (mDontReport) {
59 return;
60 }
61 try {
62 // TODO(lifecycler): Use interface callback instead of AMS.
63 ActivityManager.getService().activityPaused(token);
64 } catch (RemoteException ex) {
65 throw ex.rethrowFromSystemServer();
66 }
67 }
68
com.android.server.wm.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();
}
}
android.app.servertransaction.ClientTransaction
/** Target client. */
private IApplicationThread mClient;
public static ClientTransaction obtain(IApplicationThread client, IBinder activityToken) {
ClientTransaction instance = ObjectPool.obtain(ClientTransaction.class);
if (instance == null) {
instance = new ClientTransaction();
}
instance.mClient = client;
instance.mActivityToken = activityToken;
return instance;
}
//mClient是前面传进来的ApplicationThread实例
public void schedule() throws RemoteException {
mClient.scheduleTransaction(this);
}
android.app.ClientTransactionHandler
void scheduleTransaction(ClientTransaction transaction) {
transaction.preExecute(this);
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
android.app.ActivityThread extends android.app.ClientTransactionHandler
// An executor that performs multi-step transactions.
private final TransactionExecutor mTransactionExecutor = new TransactionExecutor(this);
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
ActivityThread.this.scheduleTransaction(transaction);
}
/**
* Extended implementation of activity launch. Used when server requests a launch or relaunch.
*/
@Override
public Activity handleLaunchActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions, Intent customIntent) {
...
final Activity a = performLaunchActivity(r, customIntent);
...
return a;
}
/** Core implementation of activity launch. */
//这个我全部贴出来了,非常的重要
//1.Context是怎么生成的
//2.activity是怎么生成的
//3.activity和Context是怎么绑定的
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
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);
}
//context的生成,下面可以看看这个
ContextImpl appContext = createBaseContextForActivity(r);
Activity activity = null;
try {
java.lang.ClassLoader cl = appContext.getClassLoader();
//Activity的生成,[Instrumentation](https://editor.csdn.net/md?articleId=109253342#androidappInstrumentation_46)中的newActivity,这个往上面看
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) {
if (!mInstrumentation.onException(activity, e)) {
throw new RuntimeException(
"Unable to instantiate activity " + component
+ ": " + e.toString(), e);
}
}
try {
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
if (localLOGV) Slog.v(
TAG, r + ": app=" + app
+ ", appName=" + app.getPackageName()
+ ", pkg=" + r.packageInfo.getPackageName()
+ ", comp=" + r.intent.getComponent().toShortString()
+ ", dir=" + r.packageInfo.getAppDir());
if (activity != null) {
CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
Configuration config = new Configuration(mCompatConfiguration);
if (r.overrideConfig != null) {
config.updateFrom(r.overrideConfig);
}
if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
+ r.activityInfo.name + " with config " + config);
Window window = null;
if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
window = r.mPendingRemoveWindow;
r.mPendingRemoveWindow = null;
r.mPendingRemoveWindowManager = null;
}
// Activity resources must be initialized with the same loaders as the
// application context.
appContext.getResources().addLoaders(
app.getResources().getLoaders().toArray(new ResourcesLoader[0]));
appContext.setOuterContext(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;
//这里调用了Activity的onCreate
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
...
return activity;
}
//Context的生成
private ContextImpl createBaseContextForActivity(ActivityClientRecord r) {
...
ContextImpl appContext = ContextImpl.createActivityContext(
this, r.packageInfo, r.activityInfo, r.token, displayId, r.overrideConfig);
...
return appContext;
}
public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,
String reason) {
...
// TODO Push resumeArgs into the activity for consideration
final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);
...
}
public ActivityClientRecord performResumeActivity(IBinder token, boolean finalStateRequest,
String reason) {
...
r.activity.performResume(r.startsNotResumed, reason);
...
}
android.app.ContextImpl
static ContextImpl createActivityContext(ActivityThread mainThread,
LoadedApk packageInfo, ActivityInfo activityInfo, IBinder activityToken, int displayId,
Configuration overrideConfiguration) {
if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
String[] splitDirs = packageInfo.getSplitResDirs();
//这个后续要去看看,暂时不知道什么时候加载的
ClassLoader classLoader = packageInfo.getClassLoader();
if (packageInfo.getApplicationInfo().requestsIsolatedSplitLoading()) {
Trace.traceBegin(Trace.TRACE_TAG_RESOURCES, "SplitDependencies");
try {
classLoader = packageInfo.getSplitClassLoader(activityInfo.splitName);
splitDirs = packageInfo.getSplitPaths(activityInfo.splitName);
} catch (NameNotFoundException e) {
// Nothing above us can handle a NameNotFoundException, better crash.
throw new RuntimeException(e);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_RESOURCES);
}
}
ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null,
activityInfo.splitName, activityToken, null, 0, classLoader, null);
context.mIsUiContext = true;
context.mIsAssociatedWithDisplay = true;
context.mIsSystemOrSystemUiContext = isSystemOrSystemUI(context);
// Clamp display ID to DEFAULT_DISPLAY if it is INVALID_DISPLAY.
displayId = (displayId != Display.INVALID_DISPLAY) ? displayId : Display.DEFAULT_DISPLAY;
final CompatibilityInfo compatInfo = (displayId == Display.DEFAULT_DISPLAY)
? packageInfo.getCompatibilityInfo()
: CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO;
final ResourcesManager resourcesManager = ResourcesManager.getInstance();
// Create the base resources for which all configuration contexts for this Activity
// will be rebased upon.
//资源设置
context.setResources(resourcesManager.createBaseTokenResources(activityToken,
packageInfo.getResDir(),
splitDirs,
packageInfo.getOverlayDirs(),
packageInfo.getApplicationInfo().sharedLibraryFiles,
displayId,
overrideConfiguration,
compatInfo,
classLoader,
packageInfo.getApplication() == null ? null
: packageInfo.getApplication().getResources().getLoaders()));
context.mDisplay = resourcesManager.getAdjustedDisplay(displayId,
context.getResources());
return context;
}
android.app.ActivityThread.ApplicationThread.H extend Handler
public void handleMessage(Message msg) {
switch (msg.what) {
...
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;
...
}
android.app.servertransaction.TransactionExecutor
> /**
* Resolve transaction.
* First all callbacks will be executed in the order they appear in the list. If a callback
* requires a certain pre- or post-execution state, the client will be transitioned accordingly.
* Then the client will cycle to the final lifecycle state if provided. Otherwise, it will
* either remain in the initial state, or last state needed by a callback.
*/
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. */
76 @VisibleForTesting
77 public void executeCallbacks(ClientTransaction transaction) {
78 final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
79 if (callbacks == null) {
80 // No callbacks to execute, return early.
81 return;
82 }
83 log("Resolving callbacks");
84
85 final IBinder token = transaction.getActivityToken();
86 ActivityClientRecord r = mTransactionHandler.getActivityClient(token);
87
88 // In case when post-execution state of the last callback matches the final state requested
89 // for the activity in this transaction, we won't do the last transition here and do it when
90 // moving to final state instead (because it may contain additional parameters from server).
91 final ActivityLifecycleItem finalStateRequest = transaction.getLifecycleStateRequest();
92 final int finalState = finalStateRequest != null ? finalStateRequest.getTargetState()
93 : UNDEFINED;
94 // Index of the last callback that requests some post-execution state.
95 final int lastCallbackRequestingState = lastCallbackRequestingState(transaction);
96
97 final int size = callbacks.size();
98 for (int i = 0; i < size; ++i) {
99 final ClientTransactionItem item = callbacks.get(i);
100 log("Resolving callback: " + item);
101 final int postExecutionState = item.getPostExecutionState();
102 final int closestPreExecutionState = mHelper.getClosestPreExecutionState(r,
103 item.getPostExecutionState());
104 if (closestPreExecutionState != UNDEFINED) {
105 cycleToPath(r, closestPreExecutionState);
106 }
107 //这个item指的就是如:
//LaunchActivityItem
//ActivityResultItem
//NewIntentItem
//ResumeActivityItem
//PauseActivityItem
108 item.execute(mTransactionHandler, token, mPendingActions);
109 item.postExecute(mTransactionHandler, token, mPendingActions);
110 `...
121 }
122 }
123
124 /** Transition to the final state if requested by the transaction. */
125 private void executeLifecycleState(ClientTransaction transaction) {
126 final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
127 if (lifecycleItem == null) {
128 // No lifecycle request, return early.
129 return;
130 }
131 log("Resolving lifecycle state: " + lifecycleItem);
132
133 final IBinder token = transaction.getActivityToken();
134 final ActivityClientRecord r = mTransactionHandler.getActivityClient(token);
135
136 if (r == null) {
137 // Ignore requests for non-existent client records for now.
138 return;
139 }
140
141 // Cycle to the state right before the final requested state.
142 cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */);
143
144 // Execute the final transition with proper parameters.
145 lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
146 lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
147 }
原本想要把所有到都贴出来,但是我感觉都贴出来,会让大家看的更迷糊,所以,把一些不是特别重要的删除了,具体的,需要大家跟着源码看一遍,这里主要的实现是在各种ClientTransaction中进行封装的,这个表示的是各种不同的状态,这是我第一次写这个,花费了很长时间,经验不足;
这个先这样吧,有时间再继续补上流程