yangchong211/YCBlogs

静态内部类引用问题

cornflower10 opened this issue · 1 comments

java中所有非静态的对象都会持有当前类的强引用,而静态对象则只会持有当前类的弱引用。声明为静态后,handler将会持有一个Activity的弱引用,而弱引用会很容易被gc回收,这样就能解决Activity结束后,gc却无法回收的情况。

3.2 弱引用解决办法
代码如下所示
private MyHandler handler = new MyHandler(this);
private static class MyHandler extends Handler{
WeakReference weakReference;
MyHandler(FirstActivity activity) {
weakReference = new WeakReference<>(activity);
}

@Override
public void handleMessage(Message msg) {
    super.handleMessage(msg);
    switch (msg.what){
    }
}

}
上面的handler已经是静态类了,为啥还在构造方法中用弱引用

  • 多谢提醒,这个我已经修改了。
  • 第二种解决方案
    - 使用弱引用解决handler内存泄漏问题,关于代码案例,可以参考我的开源项目:https://github.com/yangchong211/YCAudioPlayer中的utils-share包下的ShareDialog代码
    //自定义handler
    public static class HandlerHolder extends Handler {
        WeakReference<OnReceiveMessageListener> mListenerWeakReference;
        /**
         * @param listener 收到消息回调接口
         */
        HandlerHolder(OnReceiveMessageListener listener) {
            mListenerWeakReference = new WeakReference<>(listener);
        }
    
        @Override
        public void handleMessage(Message msg) {
            if (mListenerWeakReference!=null && mListenerWeakReference.get()!=null){
                mListenerWeakReference.get().handlerMessage(msg);
            }
        }
    }
    
    //创建handler对象
    private HandlerHolder handler = new HandlerHolder(new OnReceiveMessageListener() {
        @Override
        public void handlerMessage(Message msg) {
            switch (msg.what){
                case 1:
                    TextView textView1 = (TextView) msg.obj;
                    showBottomInAnimation(textView1);
                    break;
                case 2:
                    TextView textView2 = (TextView) msg.obj;
                    showBottomOutAnimation(textView2);
                    break;
            }
        }
    });
    
    //发送消息
    Message message = new Message();
    message.what = 1;
    message.obj = textView;
    handler.sendMessageDelayed(message,time);
    
    
    即推荐使用静态内部类 + WeakReference 这种方式。每次使用前注意判空。