当前位置:天才代写 > tutorial > 安卓教程 > Android Handler 避免内存泄漏的用法总结

Android Handler 避免内存泄漏的用法总结

2021-02-20 16:48 星期六 所属: 安卓教程 浏览:596

  Android开发设计常常会采用handler,可是大家发觉每一次应用Handler都是会出現:This Handler class should be static or leaks might occur(null)那样的提醒。Android lint便是为了更好地提醒大家,那样应用Handler会非常容易导致内存泄漏。可是你能发觉实际上改为static并没什么用。由于这并沒有处理这个问题的压根。

  最先,大家得确定,怎么会有内存泄漏?由于Handler是根据信息的。每一次new 出Handler,都是会建立一个消息队列用以解决你应用handler推送的信息,形如:handler.send***Message。因为信息的推送一直会出现先来后到的差别(假如仅仅那样都还好,终究再慢也不会很久,终究能够跑完,很有可能会延迟时间个几秒钟),可是假如你应用的是sendMessageDelayed(Message msg, long delayMillis)或postDelayed(Runnable r, long delayMillis)等推送延迟时间信息的情况下,那基础内存泄漏产生的几率早已在90%之上了

  我举个一般 的事例,便是我们在Activity中应用handler来升级UI控制,它是较为普遍的。

public class DemoActivity extends Activity {

    private Handler mHandler; 

    protected void onCreate(Bundle savedInstanceState) {
        mHandler = new Handler();
     mHandler.postDelayed(new Runnable() {
       Log.i("wytings","-----------postDelayed-------"); view.setVisibility(View.GONE); }, 50000);
        ...
    }
  ...
}

  如果我们瘋狂的对这一Activity开展全屏和坚屏转换得话,那麼Activity便会持续的被消毁和复建。理论上被关掉的Activity应当会再特殊情况下被收购 ,也就是大家的运行内存会在一定的范畴内左右波动,可是事实上,会发觉耗费的运行内存会伴随着转换全屏的频次一直渐渐地提升。这实际上早已表明大家的内存泄漏了,假如你能查看内存,你能发觉里边有大堆的DemoActivity案例没法收购 。

  这是由于view中应用的Context便是当今的Activity,而这一runnable一旦被post,便会一直存有于序列里边,直至时间到了,强制执行。意思是这一时间范围内Activity即便早已被destroy了可是这一目标還是没法收购 ,你能发觉50秒好,会出现一堆”———–postDelayed——-“的log复印出去,尽管你早已被这一运用关掉了而且你觉得即便复印也应当只复印一次……

  那怎么样才能够防止这中难题呢,假如你在网上一搜你能见到许多有关弱引用的文章内容。这的确是一个处理的方法。其基本原理便是让全部在handler里边应用的目标都变为弱引用,目地便是为了更好地能够在Android收购 运行内存的情况下,能够立即收购 掉。我真是感觉假如仅仅写这类方法的人,肯定是归属于复制党,由于这彻底是有理有据。你想一想就搞清楚,大家写这一Handler是由于我们要应用它。怎么可以根据这类弱引用的方法去解决这类难题呢?让JVM想收购 就收购 ?!假如那样,那大家还必须在应用Bitmap的情况下,recycle()干什么,还比不上立即搞成软引入得了。

  这儿必须再发布一下有关Java里边引入的专业知识:

Java引入的专业知识
强引入(Strong Reference) 默认设置引入。假如一个目标具备强引入,垃圾分类回收器决不能收购 它。在运行内存空 间不够时,Javavm虚拟机宁可抛出去OutOfMemory的不正确,使程序流程出现异常停止,也不会强引入的目标来处理内存不够难题。
软引入(SoftReference) 假如存储空间充足,垃圾分类回收器就不容易收购 它,假如存储空间不够了,便会收购 这种目标的运行内存。
弱引用(WeakReference) 在垃圾分类回收器一旦发觉了只具备弱引用的目标,无论当今存储空间充足是否,都是会收购 它的运行内存。
虚引入(PhantomReference) 假如一个目标仅拥有虚引入,那麼它就和沒有一切引入一样,在任何时刻都很有可能被垃圾分类回收。

  假如你好运气,你能遇到一些除开写弱引用这一方式后,还有一个便是handler.removeCallbacksAndMessages(null);,便是清除全部的信息和回调函数,简易一句话便是清除了消息队列。留意,不必认为你post的是个Runnable或是仅仅sendEmptyMessage。你能看一下源代码,在handler里边全是会把这种转成正统的Message,放进消息队列里边,因此 清除序列就代表着这一Handler立即被弄成原形了,自然也就可以收购 了。

  因此 ,我认为最好是的方法便是你在应用Handler的情况下,在外面的Activity或是Fragment中的关掉方式中,如onDestroy中启用一下handler.removeCallbacksAndMessages(null);就可以了,不应该改为软引入。

 

    关键字:

天才代写-代写联系方式