開發的過程中,常常見到finish()和onBackPressed()以及ondestory好像都能關掉Activity。自己抽空總結一下,首先看源碼,源碼基於'androidx.appcompat:appcompat:1.1.0'來分析。
1.Finish
android.app.Activity中源碼:
@Override
public void finish() {
//關閉activity但不關閉棧
finish(DONT_FINISH_TASK_WITH_ACTIVITY);
}
public void finishAndRemoveTask() {
//如果當前activity是處於棧底,則關閉activity的同時關閉棧
finish(FINISH_TASK_WITH_ROOT_ACTIVITY);
}
/**
* 完成當前活動並指定是否刪除與此活動關聯的任務。
*/
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);
try {
if (resultData != null) {
// 準備此{@link Intent}以退出應用程序進程。
resultData.prepareToLeaveProcess(this);
}
// 1、猜測更具finish的類別finishTask進行關閉
// 退回上一個Activity,並且會將resultCode, resultData返回。如果啓動的是startActivityForResult將會在onActivityResult響應
if (ActivityManager.getService().finishActivity(mToken, resultCode, resultData, finishTask)) {
mFinished = true;
}
} catch (RemoteException e) {
// Empty
}
} else {//如果有嵌套的父級Activity,則在父級activity關閉,此時childActivity會被自動銷燬。
mParent.finishFromChild(this);
}
//如果Intent中帶有要保存UI信息,則應該保存mInten中的信息
if (mIntent != null && mIntent.hasExtra(AutofillManager.EXTRA_RESTORE_SESSION_TOKEN)) {
getAutofillManager().onPendingSaveUi(AutofillManager.PENDING_UI_OPERATION_RESTORE, mIntent.getIBinderExtra(AutofillManager.EXTRA_RESTORE_SESSION_TOKEN));
}
}
2.OnDestroy
androidx.appcompat.app.AppCompatActivity中的源碼
@Override
protected void onDestroy() {
super.onDestroy();
getDelegate().onDestroy();
}
androidx.fragment.app.FragmentActivity中的源碼
@Override
protected void onDestroy() {
super.onDestroy();
//關閉可能包含的Fragment
mFragments.dispatchDestroy();
//讓Lifecycle處於destory狀態
mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);
}
android.app.Activity中的源碼
/**
* 1、在銷燬活動之前執行任何最後的清理。可以是人爲調用了finish,或者系統內存緊張調用了。
* 2、不能在destory中保存數據,因爲系統將簡單地殺死活動的託管過程,即可能關閉程序ondestory不一定被調用了
* 3、子類必須調用super.onDestory
*/
@CallSuper
protected void onDestroy() {
if (DEBUG_LIFECYCLE) Slog.v(TAG, "onDestroy " + this);
mCalled = true;
/**
* 關閉當前Activity管理的所有dialog,所以diaolog 不應該使用applicationContext
*/
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;
}
// 關閉任何Cursors,所以cursor不應該用ApplicationContext初始化
// 現在的版本比以前的低版本對內存泄漏的檢測和解決更加強大了
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();
}
//關閉任何 searchDialog
if (mSearchManager != null) {
mSearchManager.stopSearch();
}
//關閉ActionBar
if (mActionBar != null) {
mActionBar.onDestroy();
}
//ActivityLifecycleCallbacks 取消生命週期回調監聽
getApplication().dispatchActivityDestroyed(this);
}
3.OnDestory
androidx.activity.ComponentActivity中的源碼
public void onBackPressed() {
mOnBackPressedDispatcher.onBackPressed();
}
androidx.activity.OnBackPressedDispatcher中的源碼
/**
* 1、只有最後按得back返回鍵,才能將OnBackPressedCallback 設置爲isEnabled=true
* 2、舊版的OnbackPressed好分析一些
* 3、隨着版本的更新,軟件內部的代碼結構和構造是不斷變化的
*/
@MainThread
public void onBackPressed() {
Iterator<OnBackPressedCallback> iterator =
mOnBackPressedCallbacks.descendingIterator();
while (iterator.hasNext()) {
OnBackPressedCallback callback = iterator.next();
if (callback.isEnabled()) {
callback.handleOnBackPressed();
return;
}
}
if (mFallbackOnBackPressed != null) {
mFallbackOnBackPressed.run();
}
}
總結:
1、調用onBackPressed()方法不一定就能結束Activity。
2、調用onBackPressed()方法結束Activity,其調用的終究還是finish()方法。
3、finish()方法最後調用了Ondestory。
4、Android系統內存緊張時,可能會關閉軟件進程,此時Activity的該方法不一定必然被調用。