美文网首页Android开发程序员Android技术知识
私有内部类导致内存泄漏的解决方案

私有内部类导致内存泄漏的解决方案

作者: Android架构 | 来源:发表于2019-05-09 14:38 被阅读16次

    前言

    前几天在修复电池项目内存泄漏的地方学到了一个新的知识点.

    私有内部类(匿名的私有内部类也算)中会有一个外部类的引用,那么当内部类对象没有被销毁,外部类也不会被销毁,这一点很容易忽略从而造成内存泄漏.

    代码如下:这样的匿名内部类使用会导致OutOfMemActivity的内存泄漏

    public class OutOfMemActivity extends Activity implements View.OnClickListener{
    
        public static final String ACTION_INTENT_FILTER = "ACTION_INTENT_FILTER";
    
        private Button btn;
    
        private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                new Thread(){
                    @Override
                    public void run() {
                        super.run();
                        while (true){
                            try {
                                Thread.sleep(1000);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                            Log.i("tag","running ... "+OutOfMemActivity.this);
                        }
                    }
                }.start();
            }
        };
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_out_of_mem);
            btn = (Button)findViewById(R.id.btn_send);
            btn.setOnClickListener(this);
            IntentFilter intentFilter = new IntentFilter();
            intentFilter.addAction(ACTION_INTENT_FILTER);
            registerReceiver(broadcastReceiver,intentFilter);
        }
    
        @Override
        protected void onDestroy() {
            super.onDestroy();
            unregisterReceiver(broadcastReceiver);
        }
    
        @Override
        public void onClick(View v) {
            switch (v.getId()){
                case R.id.btn_send:
                    Intent intent = new Intent();
                    intent.setAction(ACTION_INTENT_FILTER);
                    sendBroadcast(intent);
                    break;
            }
        }
    }
    

    我们可用通过弱引用解决该问题,我们改写这个广播接收器使它成为静态内部类如下:

    private static class MyBroadcastReceiver extends BroadcastReceiver{
    
        private WeakReference<OutOfMemActivity> outOfMemActivityWeakReference;
    
        public MyBroadcastReceiver(WeakReference<OutOfMemActivity> outOfMemActivityWeakReference) {
    
            this.outOfMemActivityWeakReference = outOfMemActivityWeakReference;
        }
    
        @Override
        public void onReceive(Context context, Intent intent) {
    
            new Thread(){
    
                @Override
                public void run() {
    
                    super.run();
                    while (true){
    
                        try {
    
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
    
                            e.printStackTrace();
                        }
    
                        OutOfMemActivity outOfMemActivity = outOfMemActivityWeakReference.get();
                        Log.i("tag","running ... "+outOfMemActivity);
                    }
    
                }
    
            }.start();
        }
    
    }
    

    这样如果使用OutOfMemActivity对象,它是以弱引用传送进来,在垃圾回收器扫描到该对象的时候就会回收掉它.

    自己是从事了七年开发的Android工程师,不少人私下问我,2019年Android进阶该怎么学,方法有没有?

    没错,年初我花了一个多月的时间整理出来的学习资料,希望能帮助那些想进阶提升Android开发,却又不知道怎么进阶学习的朋友。【包括高级UI、性能优化、架构师课程、NDK、Kotlin、混合式开发(ReactNative+Weex)、Flutter等架构技术资料】,希望能帮助到您面试前的复习且找到一个好的工作,也节省大家在网上搜索资料的时间来学习。

    资料获取方式:加入Android架构交流QQ群聊:513088520 ,进群即领取资料!!!

    点击链接加入群聊【Android移动架构总群】:加入群聊

    资料大全

    相关文章

      网友评论

        本文标题:私有内部类导致内存泄漏的解决方案

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