引起内存泄露的原因:CheckList

本文探讨了在Android应用开发中如何避免内存泄露、实现单例模式的最佳实践、正确使用匿名内部类和Handler类,以及如何合理管理Dialog、Toast等UI组件的生命周期,确保应用稳定运行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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中垃圾回收机制

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值