Android内存溢出与优化(五)——防止static引用
来源:互联网 发布:淘宝改折扣影响权重吗 编辑:程序博客网 时间:2024/05/21 06:25
总篇地址:Android内存溢出与优化(零)——开题篇
前言:在Java中,如果将一个对象加上static修饰符,那么JVM虚拟机就会在内存中一直保留这个对象,这个对象不会被垃圾回收器清理,直到应用退出。为了达到目的,随意使用static修饰符是不好的表现。不过有时候又不得不使用static修饰,那么我们只用尽量避免消耗大内存的对象被static修饰或间接产生引用。下面开始Android中的代码讨论。
1.常用的Utils中的static修饰
为了方便调用,在Utils工具类中使用static修饰是我们常用的方式,不过可能存在一些问题,例如:
public class ToastUtil { private static Toast toast; public static void show(Context context, String message) { if (toast == null) { toast = Toast.makeText(context, message, Toast.LENGTH_SHORT); } else { toast.setText(message); } toast.show(); }}
分析:请看static修饰的toast对象,在show方法中这个对象同时对context持有了引用。toast是static修饰的,意味着toast将不会从内存中消失,那么其持有的引用对象context将一直保持强引用,也不会在内存中消失。如果传个占用大内存的Activity的context进来,那么将会导致大量的内存泄漏。
提供2种解决办法:
1. 将context改为context.getApplicationContext(),由于ApplicationContext是一个全局的context,会在app运行期间一直存在,就不存在内存泄露的问题了
2. 创建Application类,提供获取ApplicationContext的方法,直接在show方法中获取,不需要每次都传context了(推荐)
代码如下:
//Application类public class MyApplication extends Application { private static Context context; @Override public void onCreate() { super.onCreate(); context = getApplicationContext(); } public static Context getContext(){ return context; }}////Toast工具类public class ToastUtil { private static Toast toast; public static void show(String message) { if (toast == null) { toast = Toast.makeText(MyApplication.getContext(), message, Toast.LENGTH_SHORT); } else { toast.setText(message); } toast.show(); }}
2.单例模式中的static修饰
在单例中我也可能会有传入context这种对象,例如数据库Dao层的设计,如下:
1.AppDemo数据库创建的class
/** * AppDemo数据库创建 * @author ALion */public class AppDemoOpenHelper extends SQLiteOpenHelper { public AppDemoOpenHelper(Context context) { super(context, "appDemo.db", null, 1); } //数据库第一次创建调用 @Override public void onCreate(SQLiteDatabase db) { //字段:_id, name String sql = "CREATE TABLE t_appDemo (" + "_id INTEGER PRIMARY KEY AUTOINCREAMENT" + "name VARCHAR(20)" + )"; db.execSQL(sql); } //数据库更新时 @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { }}
2.数据库Dao封装的class
/** * 数据库Dao封装 * @author ALion */public class AppDemoDao { private static AppDemoDao sInstance = null; public AppDemoOpenHelper mHelper; private AppDemoDao(Context context) { mHelper = new AppDemoOpenHelper(context); } public static AppDemoDao getInstance(Context context) { if (sInstance == null) { synchronized (AppDemoDao.class) { if (sInstance == null) sInstance = new AppDemoDao(context); } } return sInstance; } // TODO 增加 // TODO 删除 // TODO 修改 // TODO 查询}
分析:可以看到创建数据库的AppDemoOpenHelper类需要传入一个context对象,而在Dao封装层的AppDemoDao类中又使用了单例设计模式。代码中,sInstance对象使用了static修饰,其new AppDemoDao(context)需要传入一个context对象,context被sInstance持有了强引用,从而导致了context对象的内存泄露。
解决方式同上,就不再给出代码了。
- Android内存溢出与优化(五)——防止static引用
- Android内存溢出与优化(四)——防止Handler导致的内存泄露
- Android开发之内存优化有效防止内存溢出OOM与内存泄漏
- Android内存溢出与优化(二)——不做无意义的内存消耗
- Android内存优化(1)——堆内存溢出
- 【Android】通过软引用实现图片缓存,防止内存溢出
- Android 通过软引用实现图片缓存,防止内存溢出
- Android 通过软引用实现图片缓存,防止内存溢出
- Android 通过软引用实现图片缓存,防止内存溢出
- Android 通过软引用实现图片缓存,防止内存溢出
- Android 通过软引用实现图片缓存,防止内存溢出
- Android 通过软引用实现图片缓存,防止内存溢出
- Android 通过软引用实现图片缓存,防止内存溢出
- Android通过软引用实现图片缓存,防止内存溢出
- Android内存溢出与优化(零)——开题篇
- Android内存溢出与优化(一)——不要随意new对象
- Android内存溢出与优化(三)——使用完后要close、recycle、unregister、null
- android防止内存溢出浅析(一)
- python if真假判断
- 54.NIS服务器
- QML 发光呼吸动画字体
- 没有什么是学不会的,关键是你敢不敢豁出去——《向着光亮那方》读后感
- C++中的字符串
- Android内存溢出与优化(五)——防止static引用
- 【二分匹配入门专题1】G
- js学习笔记:柯里化
- mysql(5.6)分区(三)与功能有关的分区限制
- python浅拷贝与深拷贝
- 设计模式学习(一)、策略模式
- APUE第三章学习笔记
- linux学习之路1 Linux系统安装
- 多线程之策略模式