结论:

isFinishing() 用于判断 Activity 是否正在 finish。
isDestroy() 用于判断 Activity 是否已经 destroy。
isFinishing() 返回 true 后 isDestroy() 才会返回 true。
一、isFinishing()

   /*** Check to see whether this activity is in the process of finishing,* either because you called {@link #finish} on it or someone else* has requested that it finished.  This is often used in* {@link #onPause} to determine whether the activity is simply pausing or* completely finishing.** @return If the activity is finishing, returns true; else returns false.** @see #finish*/public boolean isFinishing() {return mFinished;}

如注释所说,isFinishing 可以用在 onPause 中判断,该 Activity 是单纯的 pause,还是正在 finish。

isFinishing 只是简单地返回 mFinished 的值,而 mfinished 在 finish() 方法中被赋值。

   /*** Finishes the current activity and specifies whether to remove the task associated with this* 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) {resultData.prepareToLeaveProcess(this);}if (ActivityManager.getService().finishActivity(mToken, resultCode, resultData, finishTask)) {mFinished = true;}} catch (RemoteException e) {// Empty}} else {mParent.finishFromChild(this);}// Activity was launched when user tapped a link in the Autofill Save UI - Save UI must// be restored now.if (mIntent != null && mIntent.hasExtra(AutofillManager.EXTRA_RESTORE_SESSION_TOKEN)) {getAutofillManager().onPendingSaveUi(AutofillManager.PENDING_UI_OPERATION_RESTORE,mIntent.getIBinderExtra(AutofillManager.EXTRA_RESTORE_SESSION_TOKEN));}}

二、isDestroy()

isDestroy() 也只是返回 mDestroyed 的值。

   /*** Returns true if the final {@link #onDestroy()} call has been made* on the Activity, so this instance is now dead.*/public boolean isDestroyed() {return mDestroyed;}

mDestroyed 在 performDestroy() 中被赋值,在 onDestroy 执行前赋值。

final void performDestroy() {mDestroyed = true;mWindow.destroy();mFragments.dispatchDestroy();onDestroy();writeEventLog(LOG_AM_ON_DESTROY_CALLED, "performDestroy");mFragments.doLoaderDestroy();if (mVoiceInteractor != null) {mVoiceInteractor.detachActivity();}}

三、分析

看一下 Activity finish 的流程:

finish//【Activity】ActivityManagerNative.getDefault().finishActivity//【AMS】tr.stack.requestFinishActivityLocked//【ActivityStack】finishActivityLockedfinishCurrentActivityLockeddestroyActivityLockedr.app.thread.scheduleDestroyActivity//【ApplicationThread】                        handleDestroyActivity//【ActivityThread】performDestroyActivitymInstrumentation.callActivityOnDestroy//【Instrumentation】
performDestroy//【Activity】
onDestroy

从上面 finish() 的源码可以看出,当 ActivityManagerNative.getDefault().finishActivity 方法返回 true 后,mFinished 会被赋值。

在 finishActivity 内会调用 requestFinishActivityLocked,requestFinishActivityLocked 内会调 finishActivityLocked,finishActivityLocked 执行完后,requestFinishActivityLocked 就会返回 true。

finishActivityLocked 内会调用 r.app.thread.scheduleDestroyActivity,所以 r.app.thread.scheduleDestroyActivity 执行完后,mFinished 就被赋为 true。

而 mDestroyed 会在 r.app.thread.scheduleDestroyActivity 执行后,转移到主线程的 handler 里再进行一些操作后才被赋为 true。

所以,mFinished 为 true 比 isDestroyed 为 true 要早。即 isFinishing() 返回 true 后 isDestroy() 才会返回 true。

逻辑上讲也是这样,先进行 finishing,然后才能 destroyed。

当需要使用 Activity 时,判断 activity != null && !activity.isFinishing() 即可。


延伸:

Activity onDestroy() 调用研究

刚刚一个BUG让我发现,如果 activity 实现了一个回调接口,然后使用 this 设置给需要回调接口的方法,这种应用场景比较常见,最常见的就是实现 onClickListener 接口,然后 findViewById().setOnClickListenr(this)

如果,这个回调接口设置到了一个静态对象(单例模式),当 activity finish() 的时候(按返回键,回到桌面),则activity 不会被调用 onDestroy() ,原因可能是 activity 对象还在被引用!

此时你再点击图标回到应用,onCreate() 再次调用!

很明显,如果你把资源释放放在了 onDestroy() 里面,就会导致内存泄露!

那有没有解决办法呢?有的

你可以在 onPause() 方法里面判断 isFinishing() ,正常调用 finish() 后 activity 的回调过程是 onPause、onStop、onDestroy ,倘若出现上面的情况,只到 onPause!但是 isFinishing() 标志还是为 true !你可以释放资源了。

Activity 的 isFinishing()、isDestroy()相关推荐

  1. Activity的isFinishing()判断Activity的状态

    这里写一个准备一个关闭所有Activity的ActivityCollector Activity的isFinishing()判断Activity的状态 public class ActivityCol ...

  2. Activity 的 isFinishing()、isDestroy() 分析

    结论: isFinishing() 用于判断 Activity 是否正在 finish. isDestroy() 用于判断 Activity 是否已经 destroy. isFinishing() 返 ...

  3. Android学习之详解Activity的生命周期

    Activity Activity作为Android的四大组件之一,可见其地位非同寻常,官网介绍: 移动应用体验与桌面体验的不同之处在于,用户与应用的互动并不总是在同一位置开始,而是经常以不确定的方式 ...

  4. Android 后台线程弹对话框导致程序崩溃(is not valid; is your activity running)

    异常:android.view.WindowManager$BadTokenException: Unable to add window - token android.os.BinderProxy ...

  5. 当进度对话框和后台线程处于活动状态时,如何处理屏幕方向变化?

    我的程序在后台线程中执行一些网络活动. 在开始之前,它会弹出一个进度对话框. 该对话框在处理程序上关闭. 这一切都可以正常工作,除非对话框打开(并且背景线程正在运行)时屏幕方向发生变化. 此时,应用程 ...

  6. Android解决button反复点击问题

    public class BaseActivity extends Activity { protected boolean isDestroy;//防止反复点击设置的标志.涉及到点击打开其它Acti ...

  7. android按钮防止重复点击事件,实例详解Android解决按钮重复点击问题

    为了防止用户或者测试MM疯狂的点击某个button,写个方法防止按钮连续点击.具体实例代码如下所示: public class BaseActivity extends Activity { prot ...

  8. android开发出现的错误,android 开发 错误集锦

    1,Android Studio run出APP图标红叉解决办法: Tools -> Android -> Sync Project with Gradle Files (Android ...

  9. Android开发之自定义菊花进度条对话框

    先看下效果: 写个进度条调用类: package com.xiayiye.yhsh.flowerdialog;import android.app.Activity; import android.a ...

最新文章

  1. JAVA TCP通信基础篇——对发消息【如何解决输入流假死状态】
  2. 使用脚手架应用做单元测试
  3. codeforces1559 D2. Mocha and Diana (Hard Version)(并查集+启发式合并+随机化)
  4. php过去图片宽度,用php调整图片宽高
  5. hibernate mysql 配置文件_hibernate 框架的配置文件和映射文件以及详解
  6. raspberry pi_使用Raspberry Pi和pi-hole阻止网络上的广告
  7. OpenGL开发之旅基础知识介绍
  8. java中一个分而治之的框架ForkJoin
  9. python安装方法_Python基础入门——简介和环境配置,超实用!
  10. 致敬HarmonyOS不平凡的2020,热情背后还有多少期待
  11. ping命令使用集合
  12. 手把手教你快速搭建Struts2框架【详细教程,建议收藏】
  13. maven配置阿里镜像
  14. 算法及其复杂性分析整理
  15. AipOcr百度文字识别API Key和Secret Key申请及应用例子说明
  16. element--icon图标
  17. php cpu占有率过高怎么办,system占用cpu过高怎么办
  18. 一别两宽,各生欢喜。
  19. SAP那些事-理论篇-17-SAP项目如何整理数据
  20. 《痞子衡嵌入式半月刊》 第 26 期

热门文章

  1. 新华三H3C急招高级网络工程师
  2. php 百度网盘功能,ThinkPHP实现百度网盘下载功能,必备!
  3. css属性,运动,旋转,扭曲,3D
  4. 程序员原码/反码/补码在线计算器
  5. 【simulink simscape报错】Rigidly connected port error with Simscape Multibody Contact Forces Library
  6. mongodb 启动警告
  7. 医院管理中,什么才算得上智慧机房?
  8. 【PostgreSQL】连接pg数据库Schema切换
  9. 达梦数据库导出数据表结构为excel或html或文本(写文档用)
  10. 阚总工作第二天,写于清晨