精华内容
下载资源
问答
  • Android Context内存泄漏的情况很多,有兴趣可阅读以下文章: Android学习系列(36)--App调试内存...下面是关于Handler内存泄漏的一种解决方法: 1、将Handler声明为静态类; 2、在Handler中增加一个对Activity的


    Android Context内存泄漏的情况很多,有兴趣可阅读以下文章:


    Android学习系列(36)--App调试内存泄露之Context篇(上)


    Android学习系列(37)--App调试内存泄露之Context篇(下)


    下面是关于Handler内存泄漏的一种解决方法:

    1、将Handler声明为静态类;

    2、在Handler中增加一个对Activity的弱引用(WeakReference);

    具体实现如下:

    public class MyActivity extends Activity {
    
    	private Handler mHandler = null;
    	private final static int MSG_SECCESS = 1;
    	private final static int MSG_FAILED = 2;
    
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		mHandler = new ActivityHandler(this);
    	}
    
    	private static class ActivityHandler extends Handler {
    		private WeakReference<Activity> activityWeakReference = null;
    
    		public ActivityHandler(Activity activity) {
    			activityWeakReference = new WeakReference<Activity>(activity);
    		}
    
    		@Override
    		public void handleMessage(Message msg) {
    			// TODO Auto-generated method stub
    			MyActivity activity = (MyActivity) activityWeakReference.get();
    			if (activity != null){
    				switch(msg.what) {
    				case MSG_SECCESS:
    					break;
    				case MSG_FAILED:
    					break;
    				default:
    					break;
    				}
    			}
    		}
    	}
    
    }


    展开全文
  • Android 中 Handler内存泄露解决办法实例

    对于Handler内存泄露产生的原因这里就不说了,我就直接贴代码弱引用的解决办法。

    1.提取了一个公共的内 BaseHandleReference

    
    import android.os.Handler;
    import android.os.Looper;
    import android.os.Message;
    
    import java.lang.ref.WeakReference;
    
    public abstract class BaseHandleReference<T> extends Handler {
    
        private WeakReference<T> mReference = null;
    
        public BaseHandleReference(T reference) {
            this.mReference = new WeakReference<T>(reference);
        }
    
        public BaseHandleReference(Callback callback, T reference) {
            super(callback);
            this.mReference = new WeakReference<T>(reference);
        }
    
        public BaseHandleReference(Looper looper, T reference) {
            super(looper);
            this.mReference = new WeakReference<T>(reference);
        }
    
        public BaseHandleReference(Looper looper, Callback callback, T reference) {
            super(looper, callback);
            this.mReference = new WeakReference<T>(reference);
        }
    
        @Override
        public void handleMessage(Message msg) {
            final T reference = mReference.get();
            if (reference != null) {
                referenceHandleMessage(reference, msg);
            }
        }
    
        public abstract void referenceHandleMessage(T reference, Message msg);
    }
    

    2.使用方法 dealWithMessage里面做我们的逻辑处理就好了。

    public class TestActivity extends Activity {
    
        private Handler mHandler;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            mHandler = new TestHandle(this);
        }
    
        private void dealWithMessage(Message msg) {
        }
    
        static class TestHandle extends BaseHandleReference<TestActivity> {
    
            public TestHandle(TestActivity reference) {
                super(reference);
            }
    
            @Override
            public void referenceHandleMessage(TestActivity reference, Message msg) {
                reference.dealWithMessage(msg);
            }
        }
    
    }
    展开全文
  • 今天使用android studio 创建了一个handler内部类,程序编译时出现提示(大概意思就是Handler 类应该应该为static类型,否则有可能造成泄露。 在程序消息队列中排队的消息保持了对目标Handler类的应用。 如果...

    今天使用android studio 创建了一个handler内部类,程序编译时出现提示这里写图片描述(大概意思就是Handler 类应该应该为static类型,否则有可能造成泄露。 在程序消息队列中排队的消息保持了对目标Handler类的应用。
    如果Handler是个内部类,那 么它也会保持它所在的外部类的引用。
    为了避免泄露这个外部类,应该将Handler声明为static嵌套类,
    并且使用对外部类的弱应用。)
    上面是一段简单的Handler的使用。当使用内部类(包括匿名类)来创建Handler的时候,Handler对象会隐式地持有一个外部类对象(通常是一个Activity)的引用(不然你怎么可能通过Handler来操作Activity中的View?)。而Handler通常会伴随着一个耗时的后台线程(例如从网络拉取图片)一起出现,这个后台线程在任务执行完毕(例如图片下载完毕)之后,通过消息机制通知Handler,然后Handler把图片更新到界面。然而,如果用户在网络请求过程中关闭了Activity,正常情况下,Activity不再被使用,它就有可能在GC检查时被回收掉,但由于这时线程尚未执行完,而该线程持有Handler的引用(不然它怎么发消息给Handler?),这个Handler又持有Activity的引用,就导致该Activity无法被回收(即内存泄露),直到网络请求结束(例如图片下载完毕)。另外,如果你执行了Handler的postDelayed()方法,该方法会将你的Handler装入一个Message,并把这条Message推到MessageQueue中,那么在你设定的delay到达之前,会有一条MessageQueue -> Message -> Handler -> Activity的链,导致你的Activity被持有引用而无法被回收。
    内存泄露的危害

    只有一个,那就是虚拟机占用内存过高,导致OOM(内存溢出),程序出错。对于Android应用来说,就是你的用户打开一个Activity,使用完之后关闭它,内存泄露;又打开,又关闭,又泄露;几次之后,程序占用内存超过系统限制,FC。

    使用Handler导致内存泄露的解决方法

    方法一:通过程序逻辑来进行保护。

    1.在关闭Activity的时候停掉你的后台线程。线程停掉了,就相当于切断了Handler和外部连接的线,Activity自然会在合适的时候被回收。

    2.如果你的Handler是被delay的Message持有了引用,那么使用相应的Handler的removeCallbacks()方法,把消息对象从消息队列移除就行了。

    方法二:将Handler声明为静态类。

    静态类不持有外部类的对象,所以你的Activity可以随意被回收。代码如下:

    static class MyHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            mImageView.setImageBitmap(mBitmap);
        }
    }

    但其实没这么简单。使用了以上代码之后,你会发现,由于Handler不再持有外部类对象的引用,导致程序不允许你在Handler中操作Activity中的对象了。所以你需要在Handler中增加一个对Activity的弱引用(WeakReference):

    static class MyHandler extends Handler {
        WeakReference<Activity > mActivityReference;
    
        MyHandler(Activity activity) {
            mActivityReference= new WeakReference<Activity>(activity);
        }
    
        @Override
        public void handleMessage(Message msg) {
            final Activity activity = mActivityReference.get();
            if (activity != null) {
                mImageView.setImageBitmap(mBitmap);
            }
        }
    }

    将代码改为以上形式之后,就算完成了,也可以进行封装,如下:

    public class HandlerUtil<T> extends Handler {
        /**
         * 为了解决在activity中提示
         * Handler 类应该应该为static类型,否则有可能造成泄露。
         * 在程序消息队列中排队的消息保持了对目标Handler类的应用。
         * 如果Handler是个内部类,那 么它也会保持它所在的外部类的引用。
         * 为了避免泄露这个外部类,应该将Handler声明为static嵌套类,
         * 并且使用对外部类的弱应用。
         */
        public WeakReference<T> myActivity;
    
        public HandlerUtil(T t) {
            myActivity = new WeakReference<>(t);
    
    
        }
    
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            T second = myActivity.get();
            if (second == null) {
                return;
            }
            switch (msg.what) {
                case 1:
                    Log.i("what", msg.what + "---------");
            }
        }
    }

    延伸:什么是WeakReference?

    WeakReference弱引用,与强引用(即我们常说的引用)相对,它的特点是,GC在回收时会忽略掉弱引用,即就算有弱引用指向某对象,但只要该对象没有被强引用指向(实际上多数时候还要求没有软引用,但此处软引用的概念可以忽略),该对象就会在被GC检查到时回收掉。对于上面的代码,用户在关闭Activity之后,就算后台线程还没结束,但由于仅有一条来自Handler的弱引用指向Activity,所以GC仍然会在检查的时候把Activity回收掉。这样,内存泄露的问题就不会出现了。

    展开全文
  • 一、Handler内存泄漏原因 handler发送的消息在当前handler的消息队列中,如果此时activity finish掉了,那么消息队列的消息依旧会由handler进行处理,若此时handler声明为内部类(非静态内部类),我们知道内部类...

    一、Handler内存泄漏原因

    handler发送的消息在当前handler的消息队列中,如果此时activity finish掉了,那么消息队列的消息依旧会由handler进行处理,若此时handler声明为内部类(非静态内部类),我们知道内部类天然持有外部类的实例引用,那么就会导致activity无法回收,进而导致activity泄露。

    二、Handler内存泄漏几种情况
    1、隐式引用

    public class CameraVerifyActivity extends Activity {
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
        }
        
        private class MyHandle extends Handler {
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
        }
    }

    2、显示引用

    public class CameraVerifyActivity extends Activity {
        MyHandle myHandler;
        
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            myHandle = new MyHandle(this);
        }
        
        private class MyHandle extends Handler {
    
            public MyHandle(Activity activity) {
            }
            
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
        }
    }

    3、Handle调用Runnable

    public class CameraVerifyActivity extends Activity {
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
        }
        class MyRunnable implements Runnable {
            private View view;
            public MyRunnable(View view) {
                this.view = view;
            }
            public void run() {
                // ... do something with the view
            }
        }
    }

    三、Handler内存泄漏解决方法

    1、针对1(添加static):

    public class CameraVerifyActivity extends Activity {
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
        }
        
        private static class MyHandle extends Handler {
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
        }
    }

    2、针对2(添加弱引用):

    public class CameraVerifyActivity extends Activity {
        MyHandle myHandler;
        
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            myHandle = new MyHandle(this);
        }
        
        private static class MyHandle extends Handler {
    
            private WeakReference<CameraVerifyActivity> reference;
    
    
            MyHandle(CameraVerifyActivity activity) {
                reference = new WeakReference<CameraVerifyActivity>(activity);
            }
            
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
        }
    }

    3、同2一样

    四、Handler内存泄漏总结

    1.使用static 修饰的handler,但是一般会弱引用activity对象,因为要使用activity对象中的成员
    2.单独定义handler,同样可以弱引用activity
    3.使用内部类的handler,在onDestroy方法中removeCallbacksAndMessages
     

    展开全文
  • 在android开发过程中,我们可能会遇到过令人奔溃的OOM异常,这篇文章主要介绍了Android Handler内存泄漏详解及其解决方案,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • Handler内存泄漏分析及解决
  • 安卓handler内存泄漏分析及解决
  • Handler内存泄露原理及解决方法
  • Handler可能造成的内存泄漏以及解决办法 Android中使用Handler造成内存泄漏的原因 解决方法 弱引用介绍Handler可能造成的内存泄漏以及解决办法 java有自己的GC机制, 如果GC发现一个或者一组对象为不可到达状态,则...
  • Android 解决Handler内存泄漏问题前言更多描述解决方法自定义弱引用Handler创建BaseActivity继承使用完事 前言 最近在维护老项目的时候发现,使用handler延时处理的事件再activity结束后仍旧再执行,导致activity...
  • Handler内存泄漏

    2019-05-24 22:05:46
    关于Handler内存泄漏解决办法: 原因: handler会持有activity的匿名引用 (因为内部类的原因,具体参考内部类实现),当activity要被回收时,因为handler在做耗时操作而没有被释放,从而内存泄漏 实例化...
  • 对于handler内存泄漏分析解决+实例

    千次阅读 2016-07-17 09:48:19
    内存泄漏最终会导致内存溢出,程序就崩掉了,没有正确的使用handler就会导致这样的问题发生 比如:当A对象,被B对象所引用,当B对象没有释放时,A对象不能被回收(A短B长),A对象可能造成内存泄漏 什么是内存溢出?...
  • Android之Handler内存泄漏分析及解决 字数1121 阅读4738 评论11 喜欢32 一、介绍 首先,请浏览下面这段handler代码: public class SampleActivity extends Activity { private final Handler mLeakyHandler...
  • 发现handler内存泄漏,但是度娘的那些静态类自定义handler并没有解决问题,并且那种方式局限性很严重。然后我用现在的这种方式完全解决内存泄漏问题。人格担保有用,不行就喷我。 前言 因为Android采取了单线程...
  • Handler内存泄漏原因及解决方案 目录: 1.须知: 主线程Looper生命周期和Activity的生命周期一致。 非静态内部类,或者匿名内部类。默认持有外部类引用。 2.原因: Handler造成内存泄露的原因。非静态内部类,...
  • 当使用内部类(包括匿名类)来创建Handler的时候,Handler对象会隐式地持有一个外部类对象(通常是一个Activity)的引用(不然你怎么可能通过Handler来操作Activity中的View?)。而Handler通常会伴随着一个耗时的...
  • Android 开发中是一个比较严重的问题,系统给每一个应用分配的内存是固定的,一旦发生了内存泄露,就会导致该应用可用内存越来越小,严重时会发生 OOM 导致 Force Close,所以在平时的开发中应该避免引发内存泄漏
  • 主要给大家介绍了关于iOS WKWebView中MessageHandler内存泄漏问题的完美解决过程,文中通过示例代码介绍的非常详细,对各位iOS开发者们具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
  • 使用工具检测handler泄漏 https://blog.csdn.net/javazejian/article/details/50839443 https://blog.csdn.net/alex01550/article/details/82744191
  • 一、介绍首先,请浏览下面这段handler代码:public class SampleActivity extends Activity { private final Handler mLeakyHandler = new Handler() { @Override public void handleMessage(Message msg) { // ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 27,287
精华内容 10,914
热门标签
关键字:

handler内存泄露解决