ps:看本文之前最好先了解一下Handler源码 我们一般使用Handler使用匿名内部类的写法,也就是: 这时我们就会发现,匿名内部类的地方会报黄: 这个嘛,详细内容大家可以阅读《深入理解Java虚拟机》,前段时间刚出第三版,是紫色的,相比第二版加了很多内容。 那为什么说使用匿名内部类来使用Handler 如果此时,Activity销毁,当GC应该回收Activity对象的堆内存区域时,会从Activity实例开始向上检索引用树,如果Message此时还在消息队列中(试着发送一条延迟5min的消息,那么消息会一直在队列中直到5min后这条消息被取出交给Handler处理,在这5min之内Activity被finish掉,但是Activity指向的内存区域是无法回收的,也就是发生了内存泄漏),则这条引用链会一直引用着Activity,使Activity无法销毁,导致内存泄漏。所以,解决方法就要从源头解决,断开引用链:常用写法
private Handler mHandler = new Handler() { @Override public void handleMessage(@NonNull Message msg) { super.handleMessage(msg); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findViewById(R.id.bt_1).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mHandler.sendEmptyMessage(MainActivity.HANDLER_MAIN_CODE); } });
*这里提示的大意是:这个Handler类应该被设置为静态否则可能发生内存泄漏。*wtf???为什么会发生内存泄漏。内存泄漏到底是一个什么东西。内存泄漏是个什么东西
简单来说就是,当堆中分配的一块内存区域使用完毕,之后不会在被使用到,应该要被回收时,如果还存在一个强引用引用着这块内存区域,那么这块区域就无法被回收。此时就会发生内存泄漏。使用内部类Handler内存泄漏的原因
在handler.sengMessage时,Message拥有了Handler的引用,而内部类Handler隐式的拥有外部类(Activity)的引用。一个线程中有一个Looper,Looper中有唯一一个MessageQueue,而Message在MessageQueue中,也就是产生了下面这条引用链:
@Override protected void onDestroy() { super.onDestroy(); mHandler.removeCallbacksAndMessages(null); }
下面是基于这种方法封装的一个SafeHandler,大家如果能理解下面这个封装的SafeHandler类,那么Android 的Handler内存泄漏知识点就彻底掌握了!:package com.wiz.car.common.util; import android.app.Activity; import android.content.Context; import android.os.Handler; import android.util.Log; import java.lang.ref.WeakReference; /** * 弱引用封装Handler * @param <T> */ public abstract class SafeHandler<T> extends Handler { private final WeakReference<Context> mReference; private final WeakReference<T> mReferenceT; public SafeHandler(Context context, T t) { mReference = new WeakReference<>(context); mReferenceT = new WeakReference<>(t); } /** * 执行体 * @param t */ public abstract void execute(T t); private Runnable innerRun = new Runnable() { @Override public void run() { Context context = mReference.get(); if(context != null) { if(context instanceof Activity && ((Activity)context).isFinishing()){ release(); LogUtils.w("SafeHandler :","The task executed, but "+context.getClass().getSimpleName()+" is finishing!"); }else { T t = mReferenceT.get(); if(t != null) { execute(t); LogUtils.w("SafeHandler :","The task executed in "+context.getClass().getName()); }else{ LogUtils.w("SafeHandler :","The task executed, but callback class is null"); } } }else { release(); LogUtils.w("SafeHandler :","The task executed, but activity destroyed!"); } } }; /** * 暂停任务 */ public void stop() { removeCallbacks(innerRun); } /** * 销毁任务 */ public void release(){ stop(); mReference.clear(); mReferenceT.clear(); } /** * 延迟执行 * @param time 延迟时间 */ public void postDelayed(long time) { stop(); postDelayed(innerRun, time); } }
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算