引起内存泄露的原因:CheckList

来源:互联网 发布:淘宝软文引流怎么写 编辑:程序博客网 时间:2024/04/30 21:52

1、单例
不可取:
public class Singleton{
    private static Singleton instance;
    private Context mContext;
    private Singleton(Context mContext){
        this.mContext = mContext;
    }
    public static Singleton getInstance(Context context){
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton(context);
                }
            }
        }
        return instance;
    }
}
建议使用:
public class Singleton{
    private static Singleton instance;
    private Context mContext;
    private Singleton(Context mContext){
        this.mContext = mContext;
    }
    public static Singleton getInstance(Context context){
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton(context.getApplicationContext());
                }
            }
        }
        return instance;
    }
}
2、匿名内部类
在Android开发中,很多地方会用到匿名内部类,比如事件的监听,
Handler的消息处理等等,而一旦使用错误,也会导致内存泄露。
不可取:
private Handler handler = new Handler(){
       @override
       public void handlerMessage(Message msg){  
       }
};
正确做法:
1)、
private static class MyHandler extends Handler {
        private final WeakReference<MainActivity> mActivity;
        public MyHandler(MainActivity activity) {
            mActivity = new WeakReference<MainActivity>(activity);
        }
        @Override
        public void handleMessage(Message msg) {
            MainActivity activity = mActivity.get();
            if (activity != null) {
                 // ...
            }
        }
    }
    private final MyHandler handler = new MyHandler(this);
2)
 private static class MyRunnable implements Runnable{
    private WeakReference<TextView> textViewWeakReference;
    public MyRunnable(TextView textView){
        textViewWeakReference = new WeakReference<TextView>(textView);
    }
    @override
    public void run(){
         final TextView textView = textViewWeakReference.get();
         if(textView != null){
              textView.setText("OK");
         }
    };
}
调用:handler.postDelayed(new MyRunnable(textView),1000 * 60 * 10);
3、Handler
在使用了Handler之后,记得在onDestroy里面调用handler.removeCallbacksAndMessages(null);
当参数为null时,可以清除掉所有跟次handler相关的Runnable和Message,我们在onDestroy中调用次方法也就不会发生内存泄漏了。
4、Dialog、Toast等
Dialog使用Activity做为Context来处理,异步线程处理要注意Activity实例回收问题。
Toast也应该是Activity,不过使用Application实例好像也可以,所以如果是工具类在单例里面就是用Application实例。
只要把握住一点,凡是跟UI相关的,都应该使用Activity做为Context来处理;
其他的一些操作,Service,Activity,Application等实例都可以

对以上几点做一个总结
- 不要让生命周期长于Activity的对象持有到Activity的引用
- 尽量使用Application的Context而不是Activity的Context
- 尽量不要在Activity中使用非静态内部类,因为非静态内部类会隐式持有外部类实例的引用。如果使用静态内部类,将外部实例引用作为弱引用持有。
- 垃圾回收不能解决内存泄露,了解Android中垃圾回收机制

0 0
原创粉丝点击