1. 为什么context使用不当会导致内存泄漏
我们在日常开发中,经常用到单例模式,由于单例的静态特性使得其生命周期跟应用的生命周期一样长,所以如果使用不恰当的话,很容易造成内存泄漏。比如下面一个典型的例子,
public class AppManager {
private static AppManager instance;
private Context context;
private AppManager(Context context) {
this.context = context;
}
public static AppManager getInstance(Context context) {
if (instance == null) {
instance = new AppManager(context);
}
return instance;
}
}
这是一个普通的单例模式,当创建这个单例的时候,由于需要传入一个Context,所以这个Context的生命周期的长短至关重要:
1、如果此时传入的是 Application 的 Context,因为 Application 的生命周期就是整个应用的生命周期,所以这将没有任何问题。
2、如果此时传入的是 Activity 的 Context,当这个 Context 所对应的 Activity 退出时,由于该 Context 的引用被单例对象所持有,其生命周期等于整个应用程序的生命周期,所以当前 Activity 退出时它的内存并不会被回收,这就造成泄漏了。
正确的方式应该改为下面这种方式:
public class AppManager {
private static AppManager instance;
private Context context;
private AppManager(Context context) {
this.context = context.getApplicationContext();// 使用Application 的context
}
public static AppManager getInstance(Context context) {
if (instance == null) {
instance = new AppManager(context);
}
return instance;
}
}
2. Context的分类和作用域
其中: NO1表示 Application 和 Service 可以启动一个 Activity,不过需要创建一个新的 task 任务队列。而对于 Dialog 而言,只有在 Activity 中才能创建。
一句话总结:凡是跟UI相关的,都应该使用Activity做为Context来处理。
3. 如何在我们的应用中获取application的context
(1) 如果是在Activity和Service中,可以直接使用getApplicationContext()方法得到;
(2) 如果是在Receiver中,在onReceive(Context context, Intent intent)中会返回一个context实例,然后使用context.getApplicationContext()方法得到。
(3) 如果是在其它的一般类中,学生端请使用UIApplication.getInstance()得到。老师端请使用MApplication.getInstance()得到。
4. Context 简介以及正确使用注意点
Context的正确使用要点:
(1) 当Application的Context能搞定的情况下,并且生命周期长的对象,优先使用Application的Context。
(2) 不要让生命周期长于Activity的对象持有到Activity的引用。
(3) 尽量不要在Activity中使用非静态内部类,因为非静态内部类会隐式持有外部类实例的引用,如果使用静态内部类,将外部实例引用作为弱引用持有。
网友评论