问题:
最近在解BUG时,遇到了Activity退出,静态资源未及时进行销毁的问题,经过添加打印,发现是由于资源回收操作放在onDestroy中进行,而退出时onDestroy未及时调用导致。

原因:
经过添加LOG,发现是由于退出后返回的Activity中的初始化方法(onCreate,onStart,onResume)中存在一些耗时操作,导致消耗时间过多。而我们Activity按下back键之后的生命周期顺序是当前Activity(后续简称A)的A:onPause方法->前一个Activity(后续简称B)B:onRestart -> B:onStart -> B:onResume -> A:onStop -> A:onDestroy,由此可知导致A中onStop和onDestroy延迟调用的原因,是B中初始化操作耗时过久。

解决方法:
有几种解决方法,可以视代码情况的不同进行不同选择。
1.优化B中的初始化方法,如果B中的数据不是需要立即展示,可以将加载耗时数据的操作放在子线程中进行,并通过Handler在加载完成后发送消息更新UI,通常比较推荐使用此方法。
2.如果B中的数据无法使用异步进行操作,那么可以重写A的finish方法,在此方法中进行资源回收的操作,并在确认退出时调用此方法,不是特别推荐,有时异常退出可能会不调用此方法,导致资源无法回收。

原理分析:
我们进入到Framework中的ActivityStask.java文件中,见名知意,这个类是Android 返回栈的实现,Activity的生命周期回调也由此类进行控制,这个类的其他实现我们后续再写一篇进行详细分析,目前我们先看到其中的onStop生命周期管控方法stopActivityLocked


final void stopActivityLocked(ActivityRecord r) {if (DEBUG_SWITCH) Slog.d(TAG, "Stopping: " + r);if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_HISTORY) != 0|| (r.info.flags&ActivityInfo.FLAG_NO_HISTORY) != 0) {if (!r.finishing) {//首先判断该需要关闭的Activity是否完成了finish操作,如果没有则先完成if (!mService.mSleeping) {if (DEBUG_STATES) {Slog.d(TAG, "no-history finish of " + r);}//此处重新去请求finish操作requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,"no-history", false);} else {if (DEBUG_STATES) Slog.d(TAG, "Not finishing noHistory " + r+ " on stop because we're just sleeping");}}}if (r.app != null && r.app.thread != null) {adjustFocusedActivityLocked(r);r.resumeKeyDispatchingLocked();try {r.stopped = false;if (DEBUG_STATES) Slog.v(TAG, "Moving to STOPPING: " + r+ " (stop requested)");r.state = ActivityState.STOPPING;if (DEBUG_VISBILITY) Slog.v(TAG, "Stopping visible=" + r.visible + " for " + r);if (!r.visible) {mWindowManager.setAppVisibility(r.appToken, false);}//此处调用主线程进行stopActivity操作,如果此时我们的线程有其他耗时操作,就会导致//执行较为缓慢r.app.thread.scheduleStopActivity(r.appToken, r.visible, r.configChangeFlags);if (mService.isSleepingOrShuttingDown()) {r.setSleeping(true);}//当等待时间超过十秒时,会发送消息,强制执行操作。Message msg = mHandler.obtainMessage(STOP_TIMEOUT_MSG, r);mHandler.sendMessageDelayed(msg, STOP_TIMEOUT);} catch (Exception e) {// Maybe just ignore exceptions here...  if the process// has crashed, our death notification will clean things// up.Slog.w(TAG, "Exception thrown during pause", e);// Just in case, assume it to be stopped.r.stopped = true;if (DEBUG_STATES) Slog.v(TAG, "Stop failed; moving to STOPPED: " + r);r.state = ActivityState.STOPPED;if (r.configDestroy) {destroyActivityLocked(r, true, false, "stop-except");}}}}

由上面代码便可以知道,当我们在初始化中进行了过多耗时操作,便会导致回调延时,所以后续写代码的过程中,应该注意耗时操作不应在主线程中进行。

Android onStop onDestroy方法延时回调的问题相关推荐

  1. Android的onDestroy方法,Android编程之Activity中onDestroy()调用分析

    本文分析了Android编程之Activity中onDestroy()调用方法.分享给大家供大家参考,具体如下: 刚刚一个BUG让我发现,如果 activity 实现了一个回调接口,然后使用 this ...

  2. Android的onDestroy方法,android – 活动方法:onCreate()和onDestroy()

    当第一次创建一个活动时,系统会调用OnContentChanged()方法作为第一个方法,当一个活动被杀死时,系统的最后一次调用是OnDetachedFromWindow()方法,但是android文 ...

  3. Android的onDestroy方法,Android:onDestroy()或Application类中的类似方法

    首先:我是绝对的初学者 当我的应用退出时,我需要执行一些代码(是的,我在Android中不知道这样的事情),这对我来说行得通: -我有MyApplication,它扩展了Application. 作为 ...

  4. Android Activity onDestroy() 不回调的解决方式

    用Activity的时候,会发现如下问题: 有时候会发现Activity的onDestroy方法回调不执行,或者延时执行,比较缓慢(可以达到好几秒钟之后才调用),即使之前使用finish方式关闭Act ...

  5. android 为什么不调用onDestroy方法关闭activity

    前天有个同学突然咨询我,说关闭android的activity,为什么不直接调用ondestroy方法,而是要调用activity.finish(). 我这里总结下我的理解: 1.我们知道onDest ...

  6. Android 如何正确的重写 onDestroy() 方法

    不知道大家在写 Android 的时候有没有遇到过这样的一个疑惑:当你在重写 onDestry() 的方法时,有没有犹豫过,我们自己的方法,是应该放在 super.onDestroy() 方法的上面呢 ...

  7. python教程:实现延时回调普通函数的方法

    这篇文章主要给大家介绍了关于python中实现延时回调普通函数的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧. 回调函 ...

  8. Android onDestroy方法执行延迟的原因

    一整天过去,终于发现了自己项目中的这个问题所在,onDestroy方法执行延迟是因为-->页面跳转代码要放在当前Activity的finish()方法之前执行. 以下为整个事件的过程(仅作个人记 ...

  9. android activity生命周期(一)onCreate和onDestroy方法

    首先我们来说一下什么是生命周期 平时我们在开发软件的时候软件就有生命周期,同样 很多的事物都有自己的生命周期 一般来说 生命是不由自己的主观意识控制的. 举个例子 :人的生命周期:从出生-->到 ...

最新文章

  1. pandas 索引与列相互转化
  2. redis.conf 配置档详解
  3. git rebase 后找回消失的commit
  4. ARP欺骗原理详细介绍
  5. v4l2 框架下如何设置分辨率_【微学习】低压计量电表如何设置?(下)
  6. android数据返回,android提交数据后,得到的返回值为一个对象该怎么写?
  7. IOC控制反转(依赖注入思想)
  8. 自动化测试环境搭建--Python及selenium
  9. 浅谈:字符串、时间格式的转换
  10. 数学家是如何做量化交易的
  11. js正则 保留一位小数或者两位小数
  12. namesilo如何使用BTC支付:
  13. Shiro系列(一)——Shiro + Springboot + JWT 整合
  14. 浏览器页签icon图标的设置和获取
  15. 版本管理-SVN冲突爆红后如何通过颜色和快捷键准确无误地合并代码(一)
  16. c++ 箭头符号怎么打_C++编程基础知识二
  17. 垃圾佬口中的ECC,REG内存是啥意思
  18. 打印报表提示未安装java_解决报表打印各类问题集锦
  19. 7-6 学号识别(分数 10)
  20. 解读 | CSA 软件定义边界(SDP)标准规范 2.0 VS 1.0

热门文章

  1. 【Java】实例字段
  2. 获取用户的openId和调试微信公众号客户端
  3. Catboost参数
  4. React-Native进阶_3.触摸高亮显示TouchableHighlight
  5. 腾讯阿里混战云服务,七牛云营收增速300%以上,凭什么?
  6. 荧光染料 吲哚菁绿标记环孢霉素 ICG-Cyclosporin-A
  7. STM32编程(一)STM32 GPIO配置的4大步骤
  8. 为什么很多做设计的都转行了?
  9. 停用词扩展-基于点互信息
  10. 一周面试求职的经验教训总结