ActivityThread的handleRelaunchActivity用于处理Activity的Relaunch请求,代码如下:
//frameworks/base/core/java/android/app/ActivityThread.java
public final class ActivityThread extends ClientTransactionHandler implements ActivityThreadInternal {
public void handleRelaunchActivity(ActivityClientRecord tmp,
PendingTransactionActions pendingActions) {
// If we are getting ready to gc after going to the background, well
// we are back active so skip it.
unscheduleGcIdler();
mSomeActivitiesChanged = true;
int configChanges = 0;
// First: make sure we have the most recent configuration and most
// recent version of the activity, or skip it if some previous call
// had taken a more recent version.
synchronized (mResourcesManager) {
int N = mRelaunchingActivities.size();
IBinder token = tmp.token;
tmp = null;
for (int i=0; i<N; i++) {
ActivityClientRecord r = mRelaunchingActivities.get(i);
if (r.token == token) {
tmp = r;
configChanges |= tmp.pendingConfigChanges;
mRelaunchingActivities.remove(i);
i--;
N--;
}
}
if (tmp == null) {
if (DEBUG_CONFIGURATION) Slog.v(TAG, "Abort, activity not relaunching!");
return;
}
if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity "
+ tmp.token + " with configChanges=0x"
+ Integer.toHexString(configChanges));
}
Configuration changedConfig = mConfigurationController.getPendingConfiguration(
true /* clearPending */);
mPendingConfiguration = null;
if (tmp.createdConfig != null) {
// If the activity manager is passing us its current config,
// assume that is really what we want regardless of what we
// may have pending.
final Configuration config = mConfigurationController.getConfiguration();
if (config == null
|| (tmp.createdConfig.isOtherSeqNewer(config)
&& config.diff(tmp.createdConfig) != 0)) {
if (changedConfig == null
|| tmp.createdConfig.isOtherSeqNewer(changedConfig)) {
changedConfig = tmp.createdConfig;
}
}
}
if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity "
+ tmp.token + ": changedConfig=" + changedConfig);
// If there was a pending configuration change, execute it first.
if (changedConfig != null) {
mConfigurationController.updateDefaultDensity(changedConfig.densityDpi);
mConfigurationController.handleConfigurationChanged(changedConfig, null);
// These are only done to maintain @UnsupportedAppUsage and should be removed someday.
mCurDefaultDisplayDpi = mConfigurationController.getCurDefaultDisplayDpi();
mConfiguration = mConfigurationController.getConfiguration();
}
ActivityClientRecord r = mActivities.get(tmp.token);
if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handling relaunch of " + r);
if (r == null) {
return;
}
r.activity.mConfigChangeFlags |= configChanges;
r.mPreserveWindow = tmp.mPreserveWindow;
r.activity.mChangingConfigurations = true;
// If we are preserving the main window across relaunches we would also like to preserve
// the children. However the client side view system does not support preserving
// the child views so we notify the window manager to expect these windows to
// be replaced and defer requests to destroy or hide them. This way we can achieve
// visual continuity. It's important that we do this here prior to pause and destroy
// as that is when we may hide or remove the child views.
//
// There is another scenario, if we have decided locally to relaunch the app from a
// call to recreate, then none of the windows will be prepared for replacement or
// preserved by the server, so we want to notify it that we are preparing to replace
// everything
try {
if (r.mPreserveWindow) {
WindowManagerGlobal.getWindowSession().prepareToReplaceWindows(
r.token, true /* childrenOnly */);
}
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
handleRelaunchActivityInner(r, configChanges, tmp.pendingResults, tmp.pendingIntents,
pendingActions, tmp.startsNotResumed, tmp.overrideConfig, "handleRelaunchActivity");
if (pendingActions != null) {
// Only report a successful relaunch to WindowManager.
pendingActions.setReportRelaunchToWindowManager(true);
}
}
}
调用ActivityThreadd的handleRelaunchActivityInner方法:
//frameworks/base/core/java/android/app/ActivityThread.java
public final class ActivityThread extends ClientTransactionHandler
implements ActivityThreadInternal {
private void handleRelaunchActivityInner(ActivityClientRecord r, int configChanges,
List<ResultInfo> pendingResults, List<ReferrerIntent> pendingIntents,
PendingTransactionActions pendingActions, boolean startsNotResumed,
Configuration overrideConfig, String reason) {
// Preserve last used intent, it may be set from Activity#setIntent().
final Intent customIntent = r.activity.mIntent;
// Need to ensure state is saved.
if (!r.paused) {
performPauseActivity(r, false, reason, null /* pendingActions */);
}
if (!r.stopped) {
callActivityOnStop(r, true /* saveState */, reason);
}
handleDestroyActivity(r, false, configChanges, true, reason);
r.activity = null;
r.window = null;
r.hideForNow = false;
r.nextIdle = null;
// Merge any pending results and pending intents; don't just replace them
if (pendingResults != null) {
if (r.pendingResults == null) {
r.pendingResults = pendingResults;
} else {
r.pendingResults.addAll(pendingResults);
}
}
if (pendingIntents != null) {
if (r.pendingIntents == null) {
r.pendingIntents = pendingIntents;
} else {
r.pendingIntents.addAll(pendingIntents);
}
}
r.startsNotResumed = startsNotResumed;
r.overrideConfig = overrideConfig;
handleLaunchActivity(r, pendingActions, customIntent);
}
}
如上方法主要处理如下:
1、如果Activity没有paused,调用ActivityThread的performPauseActivity方法。
2、如果Activity没有stopped,调用ActivityThread的callActivityOnStop方法。
3、调用ActivityThread的handleDestroyActivity方法。
4、调用ActivityThread的handleLaunchActivity方法。
下面分别进行分析:
ActivityThread performPauseActivity
调用ActivityThread的performPauseActivity方法:
//frameworks/base/core/java/android/app/ActivityThread.java
public final class ActivityThread extends ClientTransactionHandler
implements ActivityThreadInternal {
private Bundle performPauseActivity(ActivityClientRecord r, boolean finished, String reason,
PendingTransactionActions pendingActions) {
if (r.paused) {
if (r.activity.mFinished) {
// If we are finishing, we won't call onResume() in certain cases.
// So here we likewise don't want to call onPause() if the activity
// isn't resumed.
return null;
}
RuntimeException e = new RuntimeException(
"Performing pause of activity that is not resumed: "
+ r.intent.getComponent().toShortString());
Slog.e(TAG, e.getMessage(), e);
}
if (finished) {
r.activity.mFinished = true;
}
// Pre-Honeycomb apps always save their state before pausing
final boolean shouldSaveState = !r.activity.mFinished && r.isPreHoneycomb();
if (shouldSaveState) {
callActivityOnSaveInstanceState(r);
}
performPauseActivityIfNeeded(r, reason);
// Notify any outstanding on paused listeners
ArrayList<OnActivityPausedListener> listeners;
synchronized (mOnPauseListeners) {
listeners = mOnPauseListeners.remove(r.activity);
}
int size = (listeners != null ? listeners.size() : 0);
for (int i = 0; i < size; i++) {
listeners.get(i).onPaused(r.activity);
}
final Bundle oldState = pendingActions != null ? pendingActions.getOldState() : null;
if (oldState != null) {
// We need to keep around the original state, in case we need to be created again.
// But we only do this for pre-Honeycomb apps, which always save their state when
// pausing, so we can not have them save their state when restarting from a paused
// state. For HC and later, we want to (and can) let the state be saved as the
// normal part of stopping the activity.
if (r.isPreHoneycomb()) {
r.state = oldState;
}
}
return shouldSaveState ? r.state : null;
}
}
调用performPauseActivityIfNeeded方法:
//frameworks/base/core/java/android/app/ActivityThread.java
public final class ActivityThread extends ClientTransactionHandler
implements ActivityThreadInternal {
private void performPauseActivityIfNeeded(ActivityClientRecord r, String reason) {
if (r.paused) {
// You are already paused silly...
return;
}
// Always reporting top resumed position loss when pausing an activity. If necessary, it
// will be restored in performResumeActivity().
reportTopResumedActivityChanged(r, false /* onTop */, "pausing");
try {
r.activity.mCalled = false;
mInstrumentation.callActivityOnPause(r.activity);
if (!r.activity.mCalled) {
throw new SuperNotCalledException("Activity " + safeToComponentShortString(r.intent)
+ " did not call through to super.onPause()");
}
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) {
if (!mInstrumentation.onException(r.activity, e)) {
throw new RuntimeException("Unable to pause activity "
+ safeToComponentShortString(r.intent) + ": " + e.toString(), e);
}
}
r.setState(ON_PAUSE);
}
}
Instrumentation callActivityOnPause
调用Instrumentation的callActivityOnPause方法:
//frameworks/base/core/java/android/app/Instrumentation.java
public class Instrumentation {
public void callActivityOnPause(Activity activity) {
activity.performPause();
}
}
Activity performPause
调用Activity的performPause方法:
Android13 Activity performPause流程分析-CSDN博客
ActivityThread callActivityOnStop
调用ActivityThread的callActivityOnStop方法:
//frameworks/base/core/java/android/app/ActivityThread.java
public final class ActivityThread extends ClientTransactionHandler
implements ActivityThreadInternal {
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);
} 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);
}
}
}
Activity performStop
调用r.activity(Activity)的performStop方法:
Android13 Activity performStop流程分析-CSDN博客
ActivityThread handleDestroyActivity
调用ActivityThread的handleDestroyActivity方法:
Android13 ActivityThread handleDestroyActivity流程分析-CSDN博客
ActivityThread handleLaunchActivity
调用ActivityThread的handleLaunchActivity方法: