// frameworks/base/core/java/android/app/Activity.java
public void finish() {
finish(DONT_FINISH_TASK_WITH_ACTIVITY); // 1
}
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
private void finish(int finishTask) {
if (mParent == null) {
int resultCode;
Intent resultData;
synchronized (this) {
resultCode = mResultCode;
resultData = mResultData;
}
if (false) Log.v(TAG, "Finishing self: token=" + mToken);
if (resultData != null) {
resultData.prepareToLeaveProcess(this);
}
if (ActivityClient.getInstance().finishActivity(mToken, resultCode, resultData,
finishTask)) { // 2
mFinished = true;
}
} else {
mParent.finishFromChild(this);
}
getAutofillClientController().onActivityFinish(mIntent);
}
// frameworks/base/core/java/android/app/ActivityClient.java
public static ActivityClient getInstance() {
return sInstance.get();
}
public boolean finishActivity(IBinder token, int resultCode, Intent resultData,
int finishTask) {
try {
return getActivityClientController().finishActivity(token, resultCode, resultData,
finishTask); // 3
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
private static IActivityClientController getActivityClientController() {
final IActivityClientController controller = INTERFACE_SINGLETON.mKnownInstance;
return controller != null ? controller : INTERFACE_SINGLETON.get();
}
// frameworks/base/core/java/android/app/IActivityClientController.aidl
interface IActivityClientController {
boolean finishActivity(in IBinder token, int code, in Intent data, int finishTask);
}
// frameworks/base/services/core/java/com/android/server/wm/ActivityClientController.java
class ActivityClientController extends IActivityClientController.Stub {
@Override
public boolean finishActivity(IBinder token, int resultCode, Intent resultData,
int finishTask) {
...
final ActivityRecord r;
synchronized (mGlobalLock) {
r = ActivityRecord.isInRootTaskLocked(token);
if (r == null) {
return true;
}
}
...
synchronized (mGlobalLock) {
...
try {
final boolean res;
final boolean finishWithRootActivity =
finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
|| (finishWithRootActivity && r == rootR)) {
mTaskSupervisor.removeTask(tr, false /*killProcess*/,
finishWithRootActivity, "finish-activity");
res = true;
r.mRelaunchReason = RELAUNCH_REASON_NONE;
} else {
r.finishIfPossible(resultCode, resultData, resultGrants, "app-request",
true /* oomAdj */); // 1
res = r.finishing;
if (!res) {
Slog.i(TAG, "Failed to finish by app-request");
}
}
return res;
} finally {
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
Binder.restoreCallingIdentity(origId);
}
}
}
}
// frameworks/base/services/core/java/com/android/server/wm/ActivityRecord.java
final ActivityTaskManagerService mAtmService;
@FinishRequest int finishIfPossible(int resultCode, Intent resultData,
NeededUriGrants resultGrants, String reason, boolean oomAdj) {
...
mAtmService.deferWindowLayout();
try {
...
finishActivityResults(resultCode, resultData, resultGrants); // 1
final boolean endTask = task.getTopNonFinishingActivity() == null
&& !task.isClearingToReuseTask();
mTransitionController.requestCloseTransitionIfNeeded(endTask ? task : this);
...
return FINISH_RESULT_REQUESTED;
} finally {
mAtmService.continueWindowLayout();
}
}
private void finishActivityResults(int resultCode, Intent resultData,
NeededUriGrants resultGrants) {
if (resultTo != null) {
...
if (mForceSendResultForMediaProjection || resultTo.isState(RESUMED)) {
final ActivityRecord resultToActivity = resultTo; // 1
mAtmService.mH.post(() -> {
synchronized (mAtmService.mGlobalLock) {
resultToActivity.sendResult(this.getUid(), resultWho, requestCode,
resultCode, resultData, resultGrants,
mForceSendResultForMediaProjection); // 2
}
});
} else {
resultTo.addResultLocked(this, resultWho, requestCode, resultCode, resultData);
}
resultTo = null;
} else if (DEBUG_RESULTS) {
Slog.v(TAG_RESULTS, "No result destination from " + this);
}
...
}
// frameworks/base/services/core/java/com/android/server/wm/ActivityRecord.java
final ActivityTaskManagerService mAtmService;
void sendResult(int callingUid, String resultWho, int requestCode, int resultCode,
Intent data, NeededUriGrants dataGrants, boolean forceSendForMediaProjection) {
...
if (forceSendForMediaProjection && attachedToProcess() &&
isState(STARTED, PAUSING, PAUSED, STOPPING, STOPPED)) {
final ClientTransaction transaction =
ClientTransaction.obtain(app.getThread(), token);
transaction.addCallback(ActivityResultItem.obtain(
List.of(new ResultInfo(resultWho, requestCode, resultCode, data))));
ActivityLifecycleItem lifecycleItem = getLifecycleItemForCurrentStateForResult();
if (lifecycleItem != null) {
transaction.setLifecycleStateRequest(lifecycleItem);
} else {
Slog.w(TAG, "Unable to get the lifecycle item for state " + mState
+ " so couldn't immediately send result");
}
try {
mAtmService.getLifecycleManager().scheduleTransaction(transaction); // 1
} catch (RemoteException e) {
Slog.w(TAG, "Exception thrown sending result to " + this, e);
}
}
addResultLocked(null /* from */, resultWho, requestCode, resultCode, data);
}
// frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
ClientLifecycleManager getLifecycleManager() {
return mLifecycleManager;
}
// frameworks/base/services/core/java/com/android/server/wm/ClientLifecycleManager.java
class ClientLifecycleManager {
void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
final IApplicationThread client = transaction.getClient();
transaction.schedule(); // 1
if (!(client instanceof Binder)) {
transaction.recycle();
}
}
}
// frameworks/base/core/java/android/app/servertransaction/ClientTransaction.java
private IApplicationThread mClient;
public void schedule() throws RemoteException {
mClient.scheduleTransaction(this);
}
// frameworks/base/core/java/android/app/ActivityThread.java
private class ApplicationThread extends IApplicationThread.Stub {
@Override
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
ActivityThread.this.scheduleTransaction(transaction);
}
}
// frameworks/base/core/java/android/app/ClientTransactionHandler.java
public abstract class ClientTransactionHandler {
// Schedule phase related logic and handlers.
/** Prepare and schedule transaction for execution. */
void scheduleTransaction(ClientTransaction transaction) {
transaction.preExecute(this);
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
}
// frameworks/base/core/java/android/app/ActivityThread.java
final H mH = new H();
private final TransactionExecutor mTransactionExecutor = new TransactionExecutor(this);
private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
...
Message msg = Message.obtain();
msg.what = what;
msg.obj = obj;
msg.arg1 = arg1;
msg.arg2 = arg2;
if (async) {
msg.setAsynchronous(true);
}
mH.sendMessage(msg); // 1
}
class H extends Handler {
public void handleMessage(Message msg) {
...
case EXECUTE_TRANSACTION:
final ClientTransaction transaction = (ClientTransaction) msg.obj;
mTransactionExecutor.execute(transaction); // 2
if (isSystem()) {
transaction.recycle();
}
break;
...
}
}
// frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java
public void execute(ClientTransaction transaction) {
if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Start resolving transaction");
final IBinder token = transaction.getActivityToken();
if (token != null) {
final Map<IBinder, ClientTransactionItem> activitiesToBeDestroyed =
mTransactionHandler.getActivitiesToBeDestroyed();
final ClientTransactionItem destroyItem = activitiesToBeDestroyed.get(token);
if (destroyItem != null) {
if (transaction.getLifecycleStateRequest() == destroyItem) {
activitiesToBeDestroyed.remove(token);
}
if (mTransactionHandler.getActivityClient(token) == null) {
Slog.w(TAG, tId(transaction) + "Skip pre-destroyed transaction:\n"
+ transactionToString(transaction, mTransactionHandler));
return;
}
}
}
if (DEBUG_RESOLVER) Slog.d(TAG, transactionToString(transaction, mTransactionHandler));
executeCallbacks(transaction); // 1
executeLifecycleState(transaction);
mPendingActions.clear();
if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "End resolving transaction");
}
/** Cycle through all states requested by callbacks and execute them at proper times. */
@VisibleForTesting
public void executeCallbacks(ClientTransaction transaction) {
final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
if (callbacks == null || callbacks.isEmpty()) {
// No callbacks to execute, return early.
return;
}
if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Resolving callbacks in transaction");
final IBinder token = transaction.getActivityToken(); // 2
ActivityClientRecord r = mTransactionHandler.getActivityClient(token);
final ActivityLifecycleItem finalStateRequest = transaction.getLifecycleStateRequest();
final int finalState = finalStateRequest != null ? finalStateRequest.getTargetState()
: UNDEFINED;
final int lastCallbackRequestingState = lastCallbackRequestingState(transaction);
final int size = callbacks.size();
for (int i = 0; i < size; ++i) {
final ClientTransactionItem item = callbacks.get(i);
if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Resolving callback: " + item);
final int postExecutionState = item.getPostExecutionState();
if (item.shouldHaveDefinedPreExecutionState()) {
final int closestPreExecutionState = mHelper.getClosestPreExecutionState(r,
item.getPostExecutionState());
if (closestPreExecutionState != UNDEFINED) {
cycleToPath(r, closestPreExecutionState, transaction);
}
}
item.execute(mTransactionHandler, token, mPendingActions); // 3
item.postExecute(mTransactionHandler, token, mPendingActions);
if (r == null) {
// Launch activity request will create an activity record.
r = mTransactionHandler.getActivityClient(token);
}
if (postExecutionState != UNDEFINED && r != null) {
final boolean shouldExcludeLastTransition =
i == lastCallbackRequestingState && finalState == postExecutionState;
cycleToPath(r, postExecutionState, shouldExcludeLastTransition, transaction);
}
}
}
// frameworks/base/core/java/android/app/servertransaction/DestroyActivityItem.java
public class DestroyActivityItem extends ActivityLifecycleItem {
@Override
public void execute(ClientTransactionHandler client, ActivityClientRecord r,
PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityDestroy");
client.handleDestroyActivity(r, mFinished, mConfigChanges,
false /* getNonConfigInstance */, "DestroyActivityItem");
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
}
// frameworks/base/core/java/android/app/ClientTransactionHandler.java
public abstract class ClientTransactionHandler {
/** Destroy the activity. */
public abstract void handleDestroyActivity(@NonNull ActivityClientRecord r,
boolean finishing, int configChanges, boolean getNonConfigInstance, String reason);
}
// frameworks/base/core/java/android/app/ActivityThread.java
@Override
public void handleDestroyActivity(ActivityClientRecord r, boolean finishing,
int configChanges, boolean getNonConfigInstance,
String reason) {
performDestroyActivity(r, finishing, configChanges, getNonConfigInstance, reason); // 1
...
}
/** Core implementation of activity destroy call. */
void performDestroyActivity(ActivityClientRecord r, boolean finishing,
int configChanges, boolean getNonConfigInstance, String reason) {
Class<? extends Activity> activityClass;
if (localLOGV) Slog.v(TAG, "Performing finish of " + r);
activityClass = r.activity.getClass();
r.activity.mConfigChangeFlags |= configChanges;
if (finishing) {
r.activity.mFinished = true;
}
performPauseActivityIfNeeded(r, "destroy");
if (!r.stopped) {
callActivityOnStop(r, false /* saveState */, "destroy");
}
...
try {
r.activity.mCalled = false;
mInstrumentation.callActivityOnDestroy(r.activity); // 2
...
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) {
...
}
r.setState(ON_DESTROY);
...
}
// frameworks/base/core/java/android/app/Instrumentation.java
public void callActivityOnDestroy(Activity activity) {
activity.performDestroy();
}
// frameworks/base/core/java/android/app/Activity.java
final void performDestroy() {
...
dispatchActivityPreDestroyed();
mDestroyed = true;
mWindow.destroy();
mFragments.dispatchDestroy();
onDestroy(); // 1
...
dispatchActivityPostDestroyed();
Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
}
@CallSuper
protected void onDestroy() {
if (DEBUG_LIFECYCLE) Slog.v(TAG, "onDestroy " + this);
mCalled = true;
getAutofillClientController().onActivityDestroyed();
// 2 dismiss any dialogs we are managing. 关闭所有被管理的 dialog
if (mManagedDialogs != null) {
final int numDialogs = mManagedDialogs.size();
for (int i = 0; i < numDialogs; i++) {
final ManagedDialog md = mManagedDialogs.valueAt(i);
if (md.mDialog.isShowing()) {
md.mDialog.dismiss();
}
}
mManagedDialogs = null;
}
// 3 close any cursors we are managing. 关闭所有被管理的 Cursor
synchronized (mManagedCursors) {
int numCursors = mManagedCursors.size();
for (int i = 0; i < numCursors; i++) {
ManagedCursor c = mManagedCursors.get(i);
if (c != null) {
c.mCursor.close();
}
}
mManagedCursors.clear();
}
// 4 Close any open search dialog 关闭系统搜索服务的弹窗
if (mSearchManager != null) {
mSearchManager.stopSearch();
}
if (mActionBar != null) {
mActionBar.onDestroy();
}
// 5 发送 Destroyed 事件,执行所有注册的 ActivityLifecycleCallbacks 的 onActivityDestroyed 回调
dispatchActivityDestroyed();
// 内容捕获服务
notifyContentCaptureManagerIfNeeded(CONTENT_CAPTURE_STOP);
if (mUiTranslationController != null) {
mUiTranslationController.onActivityDestroyed();
}
if (mDefaultBackCallback != null) {
getOnBackInvokedDispatcher().unregisterOnBackInvokedCallback(mDefaultBackCallback);
mDefaultBackCallback = null;
}
if (mCallbacksController != null) {
mCallbacksController.clearCallbacks();
}
}
至此,Activity 整个销毁流程就结束了。