Anroid Q 之onStop执行时机
我们都知道在activity切换过程中,譬如A启动到BActivity,在启动完成之后一般的A会回调其onStop生命周期,那么我们就来看看何时以及何种情况下A的onStop会被回调
1:停止Activity的流程
1:在resume具体的activity时,当目标进程的ActivityThread的handleResumeActivity之后,会创建一个Idler,并且添加到主线程的消息队列中去
if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward=" + isForward);
WindowManager.LayoutParams l = r.window.getAttributes();
if ((l.softInputMode
& WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)
!= forwardBit) {
l.softInputMode = (l.softInputMode
& (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION))
| forwardBit;
if (r.activity.mVisibleFromClient) {
ViewManager wm = a.getWindowManager();
View decor = r.window.getDecorView();
wm.updateViewLayout(decor, l);
}
}
r.activity.mVisibleFromServer = true;
mNumVisibleActivities++;
if (r.activity.mVisibleFromClient) {
r.activity.makeVisible();
}
}
r.nextIdle = mNewActivities;
mNewActivities = r;
if (localLOGV) Slog.v(TAG, "Scheduling idle handler for " + r);
Looper.myQueue().addIdleHandler(new Idler());------->Looper对应的是主线程的Looper,消息队列是主线程的
2:handleResumeActivity执行之后已经完成了启动activity的所有动作,接下来就是Idle状态了,此时可以执行一些Idle的行为,而Idler类内部处理函数会调用activityIdle方法
private class Idler implements MessageQueue.IdleHandler {
@Override
public final boolean queueIdle() {
ActivityClientRecord a = mNewActivities;
boolean stopProfiling = false;
if (mBoundApplication != null && mProfiler.profileFd != null
&& mProfiler.autoStopProfiler) {
stopProfiling = true;
}
if (a != null) {
mNewActivities = null;
IActivityTaskManager am = ActivityTaskManager.getService();
ActivityClientRecord prev;
do {
if (localLOGV) Slog.v(
TAG, "Reporting idle of " + a +
" finished=" +
(a.activity != null && a.activity.mFinished));
if (a.activity != null && !a.activity.mFinished) {
try {
am.activityIdle(a.token, a.createdConfig, stopProfiling);---->调用activityIdle方法
a.createdConfig = null;
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
prev = a;
a = a.nextIdle;
prev.nextIdle = null;
} while (a != null);
}
if (stopProfiling) {
mProfiler.stopProfiling();
}
applyPendingProcessState();
return false;
}
}
3:activityIdle的具体实现
进入到ActivityTaskManagerService.java
@Override
public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
final long origId = Binder.clearCallingIdentity();
try {
WindowProcessController proc = null;
synchronized (mGlobalLock) {
ActivityStack stack = ActivityRecord.getStackLocked(token);--->根据token获取对应的Stack
if (stack == null) {
return;
}
final ActivityRecord r = mStackSupervisor.activityIdleInternalLocked(token,
false /* fromTimeout */, false /* processPausingActivities */, config);
if (r != null) {
proc = r.app;
}
if (stopProfiling && proc != null) {
proc.clearProfilerIfNeeded();
}
}
} finally {
Binder.restoreCallingIdentity(origId);
}
}
4:ActivityStackSuperVisor的activityIdleInternalLocked
final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
boolean processPausingActivities, Configuration config) {
......................................
ActivityRecord r = ActivityRecord.forTokenLocked(token);----->获取ActivityRecord对象
if (r != null) {
if (DEBUG_IDLE) Slog.d(TAG_IDLE, "activityIdleInternalLocked: Callers="
+ Debug.getCallers(4));
mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
r.finishLaunchTickingLocked();
if (fromTimeout) {
reportActivityLaunchedLocked(fromTimeout, r, INVALID_DELAY,
-1 /* launchState */);
}
// This is a hack to semi-deal with a race condition
// in the client where it can be constructed with a
// newer configuration from when we asked it to launch.
// We'll update with whatever configuration it now says
// it used to launch.
if (config != null) {
r.setLastReportedGlobalConfiguration(config);
}
// We are now idle. If someone is waiting for a thumbnail from
// us, we can now deliver.
r.idle = true;
//Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
// Check if able to finish booting when device is booting and all resumed activities
// are idle.
if ((mService.isBooting() && mRootActivityContainer.allResumedActivitiesIdle())
|| fromTimeout) {
booting = checkFinishBootingLocked();
}
// When activity is idle, we consider the relaunch must be successful, so let's clear
// the flag.
r.mRelaunchReason = RELAUNCH_REASON_NONE;
}
if (mRootActivityContainer.allResumedActivitiesIdle()) {
if (r != null) {
mService.scheduleAppGcsLocked();
}
if (mLaunchingActivityWakeLock.isHeld()) {
mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
if (VALIDATE_WAKE_LOCK_CALLER &&
Binder.getCallingUid() != Process.myUid()) {
throw new IllegalStateException("Calling must be system uid");
}
mLaunchingActivityWakeLock.release();
}
mRootActivityContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
}
// Atomically retrieve all of the other things to do.
final ArrayList<ActivityRecord> stops = processStoppingActivitiesLocked(r,
true /* remove */, processPausingActivities);----------->处理stopping状态的activity
NS = stops != null ? stops.size() : 0;
if ((NF = mFinishingActivities.size()) > 0) {
finishes = new ArrayList<>(mFinishingActivities);
mFinishingActivities.clear();
}
if (mStartingUsers.size() > 0) {
startingUsers = new ArrayList<>(mStartingUsers);
mStartingUsers.clear();
}
// Stop any activities that are scheduled to do so but have been
// waiting for the next one to start.
for (int i = 0; i < NS; i++) {
r = stops.get(i);
final ActivityStack stack = r.getActivityStack();
if (stack != null) {
if (r.finishing) {----------------->如果正处于finishing状态
stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false,
"activityIdleInternalLocked");
} else {
stack.stopActivityLocked(r);------->停止该activity
}
}
}
// Finish any activities that are scheduled to do so but have been
// waiting for the next one to start.
for (int i = 0; i < NF; i++) {
r = finishes.get(i);----------------------------------------->处理finish状态的activity
final ActivityStack stack = r.getActivityStack();
if (stack != null) {
activityRemoved |= stack.destroyActivityLocked(r, true, "finish-idle");
}
}
if (!booting) {
// Complete user switch
if (startingUsers != null) {
for (int i = 0; i < startingUsers.size(); i++) {
mService.mAmInternal.finishUserSwitch(startingUsers.get(i));
}
}
}
mService.mH.post(() -> mService.mAmInternal.trimApplications());
//dump();
//mWindowManager.dump();
if (activityRemoved) {
mRootActivityContainer.resumeFocusedStacksTopActivities();
}
return r;
}
5:ActivityStack之stopActivityLocked
final void stopActivityLocked(ActivityRecord r) {
if (DEBUG_SWITCH) Slog.d(TAG_SWITCH, "Stopping: " + r);
//如果intent中有FLAG_ACTIVITY_NO_HISTORY获取ActivityInfo中有FLAG_NO_HISTORY
那么调用requestFinishActivityLocked销毁该activity,也就是说如果从A---->B--->C,
如果B包含该flag,那么从C直接返回到了A
if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
|| (r.info.flags&ActivityInfo.FLAG_NO_HISTORY) != 0) {
if (!r.finishing) {
if (!shouldSleepActivities()) {
if (DEBUG_STATES) Slog.d(TAG_STATES, "no-history finish of " + r);
if (requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
"stop-no-history", false)) {
// If {@link requestFinishActivityLocked} returns {@code true},
// {@link adjustFocusedActivityStack} would have been already called.
r.resumeKeyDispatchingLocked();
return;
}
} else {
if (DEBUG_STATES) Slog.d(TAG_STATES, "Not finishing noHistory " + r
+ " on stop because we're just sleeping");
}
}
}
if (r.attachedToProcess()) {----->如果r的进程和主线程都存在
adjustFocusedActivityStack(r, "stopActivity");---->调整焦点activity
r.resumeKeyDispatchingLocked();---------->暂时允许r接受事件
try {
r.stopped = false;
if (DEBUG_STATES) Slog.v(TAG_STATES,
"Moving to STOPPING: " + r + " (stop requested)");
r.setState(STOPPING, "stopActivityLocked");---->设置成stopping状态
if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
"Stopping visible=" + r.visible + " for " + r);
if (!r.visible) {
r.setVisible(false);----->设置成不可见
}
EventLogTags.writeAmStopActivity(
r.mUserId, System.identityHashCode(r), r.shortComponentName);
//事务StopActivityItem
mService.getLifecycleManager().scheduleTransaction(r.app.getThread(), r.appToken,
StopActivityItem.obtain(r.visible, r.configChangeFlags));
if (shouldSleepOrShutDownActivities()) {
r.setSleeping(true);
}
Message msg = mHandler.obtainMessage(STOP_TIMEOUT_MSG, r);----->设置超时消息
mHandler.sendMessageDelayed(msg, STOP_TIMEOUT);
} catch (Exception e) {
// Maybe just ignore exceptions here... if the process
// has crashed, our death notification will clean things
// up.
Slog.w(TAG, "Exception thrown during pause", e);
// Just in case, assume it to be stopped.
r.stopped = true;
if (DEBUG_STATES) Slog.v(TAG_STATES, "Stop failed; moving to STOPPED: " + r);
r.setState(STOPPED, "stopActivityLocked");
if (r.deferRelaunchUntilPaused) {
destroyActivityLocked(r, true, "stop-except");
}
}
}
}
6:LifecycleManager处理scheduleTransaction
这里我们在activity启动过程中已经分析过,最终调用的ActivityLifecycleItem的execute方法
public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStop");
client.handleStopActivity(token, mShowWindow, mConfigChanges, pendingActions,
true /* finalStateRequest */, "STOP_ACTIVITY_ITEM");---->回调ActivityThread的handleStopActivity方法
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
7:ActivityThread的handleStopActivity
public void handleStopActivity(IBinder token, boolean show, int configChanges,
PendingTransactionActions pendingActions, boolean finalStateRequest, String reason) {
final ActivityClientRecord r = mActivities.get(token);
r.activity.mConfigChangeFlags |= configChanges;
final StopInfo stopInfo = new StopInfo();
performStopActivityInner(r, stopInfo, show, true /* saveState */, finalStateRequest,
reason);-------------------------->会回调onStop方法
if (localLOGV) Slog.v(
TAG, "Finishing stop of " + r + ": show=" + show
+ " win=" + r.window);
updateVisibility(r, show);----------------------->更新可见性
// Make sure any pending writes are now committed.
if (!r.isPreHoneycomb()) {
QueuedWork.waitToFinish();
}
stopInfo.setActivity(r);
stopInfo.setState(r.state);
stopInfo.setPersistentState(r.persistentState);
pendingActions.setStopInfo(stopInfo);
mSomeActivitiesChanged = true;
}
8:performStopActivityInner
private void performStopActivityInner(ActivityClientRecord r, StopInfo info, boolean keepShown,
boolean saveState, boolean finalStateRequest, String reason) {
if (localLOGV) Slog.v(TAG, "Performing stop of " + r);
if (r != null) {
if (!keepShown && r.stopped) {
if (r.activity.mFinished) {------------------------------->如果已经stopped了,不做处理
// If we are finishing, we won't call onResume() in certain
// cases. So here we likewise don't want to call onStop()
// if the activity isn't resumed.
return;
}
if (!finalStateRequest) {
final RuntimeException e = new RuntimeException(
"Performing stop of activity that is already stopped: "
+ r.intent.getComponent().toShortString());
Slog.e(TAG, e.getMessage(), e);
Slog.e(TAG, r.getStateString());
}
}
// One must first be paused before stopped...
performPauseActivityIfNeeded(r, reason);----------------->先onPause,该方法是判断是否需要onPause
if (info != null) {
try {
// First create a thumbnail for the activity...
// For now, don't create the thumbnail here; we are
// doing that by doing a screen snapshot.
info.setDescription(r.activity.onCreateDescription());
} catch (Exception e) {
if (!mInstrumentation.onException(r.activity, e)) {
throw new RuntimeException(
"Unable to save state of activity "
+ r.intent.getComponent().toShortString()
+ ": " + e.toString(), e);
}
}
}
if (!keepShown) {--------------------------------->如果不需要保持可见,那么才回调
callActivityOnStop(r, saveState, reason);
}
}
}
9:callActivityOnStop
private void callActivityOnStop(ActivityClientRecord r, boolean saveState, String reason) {
// Before P onSaveInstanceState was called before onStop, starting with P it's
// called after. Before Honeycomb state was always saved before onPause.
final boolean shouldSaveState = saveState && !r.activity.mFinished && r.state == null
&& !r.isPreHoneycomb();
final boolean isPreP = r.isPreP();
if (shouldSaveState && isPreP) {
callActivityOnSaveInstanceState(r);--------------------->保存状态
}
try {
r.activity.performStop(r.mPreserveWindow, reason);------>回调activity的onStop方法
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) {
if (!mInstrumentation.onException(r.activity, e)) {
throw new RuntimeException(
"Unable to stop activity "
+ r.intent.getComponent().toShortString()
+ ": " + e.toString(), e);
}
}
r.setState(ON_STOP);---------------------------------------->保存状态值
if (shouldSaveState && !isPreP) {
callActivityOnSaveInstanceState(r);
}
}
总结
1:pause发生在目标Activity启动之前,stop发生在目标Activity启动之后
2:被调方式不同,pause是ams有意调用的,stop则是无意调用的。onStop不一定会回调,取决于其是否可见
网友评论