匿名内部类与内存泄漏【每日一思】

997 阅读1分钟

【每日一思】安卓小白的每日记录,再忙碌也不能放弃每天的思考

问题起因

同事在分析app整体内存泄漏时发现某SDK会一直持有activity,导致内存泄漏。

分析堆栈,发现是初始化某SDK的回调使用了匿名内部类。

public calss classA extend classB{
    xxxManager.init(context, builder.build(), new InitializationListener() {
    @Override
    public void onSuccess() {
        LogCat.d("init success");
    }

    @Override
    public void onError(int err, String msg) {
        LogCat.d("err: " + err + " " + msg);
    }
    });
}
public class classB{
    protect Activity mActivity;
    .....
}

原因与修改

匿名内部类会持有外部类的引用,而外部类的父类持有了Activity对象,因为不清楚SDK内部的逻辑,理论上当SDK的生命周期大于该Activity的生命周期时,就可能导致Activity对象不能被回收,产生内存泄漏现象。

修改方法也很简单,静态的内部类是不会持有外部类的对象的,将该回调改为静态内部类实现即可。

public calss classA extend classB{
    xxxManager.init(context, builder.build(),new MyInitializationListener);
    
    static class MyInitializationListener implements InitializationListener{

        @Override
        public void onSuccess() {
            LogCat.d("init success");
        }

        @Override
        public void onError(int err, String msg) {
            LogCat.d("err: " + err + " " + msg);
        }
    }
}

思考与挖坑

在使用内部类时要注意内存泄漏问题,尤其在安卓开发中,经常会有类持有Activity的情况。

挖坑1:安卓内存泄漏整理。

挖坑2: 安卓内存泄漏工具。

挖坑3: 内部类使用注意点。

后面放到【每周一点】系列中去更新吧,希望有回来填坑的时间。