内存泄漏之activitiy被单例绑定
2016-07-09 14:09
369 查看
public class LoginManager {
在LoginActivity中
public class LoginActivity extends Activity {
正确的获取context的方式
public class LoginManager {
修改方式也非常简单我们单例中context不再持有Activity的context而是持有Application的context即可,因为Application本来就是单例,所以这样就不会存在内存泄漏的的现象了。
单例模式中通过内部类持有activity对象
public class TestManager {
public static final TestManager INSTANCE = new TestManager();
private List mListenerList;
}
interface MyListener {
public void onSomeThingHappen();
}
然后是activity:
public class TestActivity extends AppCompatActivity {
}
修改以上代码,避免内存泄漏,在activity中添加以下代码:`
@Override
protected void onDestroy() {
testManager.unregisterListener(mMyListener);
super.onDestroy();
}
AsyncTask不正确使用造成的内存泄漏
介绍完以上两种情况的内存泄漏后,我们在来看一种更加容易被忽略的内存泄漏现象,对于AsyncTask不正确使用造成内存泄漏的问题。
mTask=new AsyncTask
private Context context; private static LoginManager manager; public static LoginManager getInstance(Context context) { if (manager == null) manager = new LoginManager(context); return manager; } private LoginManager(Context context) { this.context = context; }
在LoginActivity中
public class LoginActivity extends Activity {
private LoginManager loginManager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_login); loginManager = LoginManager.getInstance(this); } 这种方式大家应该一看就明白问题在哪里了,在LoginManager的单例中context持有了LoginActivity的this对象,即使登录成功后我们跳转到了其他Activity页面,LoginActivity的对象仍然得不到回收因为他被单例所持有,而单例的生命周期是同Application保持一致的。
正确的获取context的方式
public class LoginManager {
private Context context; private static LoginManager manager; public static LoginManager getInstance(Context context) { if (manager == null) manager = new LoginManager(context); return manager; } private LoginManager(Context context) { this.context = context.getApplicationContext(); }
修改方式也非常简单我们单例中context不再持有Activity的context而是持有Application的context即可,因为Application本来就是单例,所以这样就不会存在内存泄漏的的现象了。
单例模式中通过内部类持有activity对象
第一种方式内存泄漏太过与明显,相信大家都不会犯这种错误,接下来要介绍的这种泄漏方式会比较不那么容易发现,内部类的使用造成activity对象被单例持有。 还是看代码再分析,下面是一个单例的类:
public class TestManager {
public static final TestManager INSTANCE = new TestManager();
private List mListenerList;
private TestManager() { mListenerList = new ArrayList<MyListener>(); } public static TestManager getInstance() { return INSTANCE; } public void registerListener(MyListener listener) { if (!mListenerList.contains(listener)) { mListenerList.add(listener); } } public void unregisterListener(MyListener listener) { mListenerList.remove(listener); }
}
interface MyListener {
public void onSomeThingHappen();
}
然后是activity:
public class TestActivity extends AppCompatActivity {
private MyListener mMyListener=new MyListener() { @Override public void onSomeThingHappen() { } }; private TestManager testManager=TestManager.getInstance(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_test); testManager.registerListener(mMyListener); }
}
我们知道在java中,非静态的内部类的对象都是会持有指向外部类对象的引用的,因此我们将内部类对象mMyListener让单例所持有时,由于mMyListener引用了我们的activity对象,因此造成activity对象也不能被回收了,从而出现内存泄漏现象。
修改以上代码,避免内存泄漏,在activity中添加以下代码:`
@Override
protected void onDestroy() {
testManager.unregisterListener(mMyListener);
super.onDestroy();
}
AsyncTask不正确使用造成的内存泄漏
介绍完以上两种情况的内存泄漏后,我们在来看一种更加容易被忽略的内存泄漏现象,对于AsyncTask不正确使用造成内存泄漏的问题。
mTask=new AsyncTask
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories