开发的过程中,常常见到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的该方法不一定必然被调用。