美文网首页
Android Handler 解决循环引用

Android Handler 解决循环引用

作者: yuezishenyou | 来源:发表于2019-04-15 14:26 被阅读0次
    案例
    public class MainActivity extends AppCompatActivity {
    
        private Handler mHandler = new Handler(){
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                switch (msg.what){
                     ...
                }
            }
        };
        
            @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            mBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
    
    
            mHandler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    ...
                }
            }, 1000000);
    
        }
    }
    
    
    (1)外部类Activity中定义了一个非静态内部类Handler,非静态内部类默认持有对外部类的引用。如果外部Activity突然关闭了,但是MessageQueue中的消息还没处理完,那么Handler就会一直持有对外部Activty的引用,垃圾回收器无法回收Activity,从而导致内存泄漏。
    (2) 如上代码,在postDelayed中,我们在参数中传入一个非静态内部类Runnable,这同样会造成内存泄漏,假如此时关闭了Activity,那么垃圾回收器在接下来的1000000ms内都无法回收Activity,造成内存泄漏。
    
    解决方案:
    (1) 将非静态内部类Handler和Runnable转为静态内部类,因为非静态内部类(匿名内部类)都会默认持有对外部类的强引用。
    (2) 改成静态内部类后,对外部类的引用设为弱引用,因为在垃圾回收时,会自动将弱引用的对象回收。
    
    
    public class HandlerActivity extends AppCompatActivity {
    
        private final MyHandler mHandler = new MyHandler(this);
    
        private static final Runnable mRunnable = new Runnable() {
            @Override
            public void run() {
                // 操作
            }
        };
    
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_fourth);
    
            mHandler.postDelayed(mRunnable, 1000*10);
            
            finish();   
        }
    
    
        private static class MyHandler extends Handler {
            WeakReference<HandlerActivity> mWeakActivity;
    
            public MyHandler(HandlerActivity activity) {
                this.mWeakActivity = new WeakReference<HandlerActivity>(activity);
            }
    
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                final HandlerActivity mActivity = mWeakActivity.get();
                if (mActivity != null) {
                    // 处理消息
                }
            }
        }
    
    }
    

    相关文章

      网友评论

          本文标题:Android Handler 解决循环引用

          本文链接:https://www.haomeiwen.com/subject/tvyuwqtx.html