Android 防内存泄露的AsyncTask--WeakAsyncTask
来源:互联网 发布:mac air 电池 编辑:程序博客网 时间:2024/04/29 10:06
AsyncTask是我在项目中经常会用到的一个类,尤其是在操作数据库的时候,之前也用它写过网络请求框架,这个网络框架在用在viewpager加载数据时总是会出现很奇怪的现象,因为AsyncTask是串行执行(android1.6–2.3版本的AsyncTask是并行执行的),所以之后的网络框架换成了线程池,其实AsyncTask也不适合用来做比较耗时请求网络。
生命周期
AsyncTask会一直执行子线程doInBackground()方法,直到方法执行结束,一旦doInBackground()方法执行完,会根据条件来执行不的操作:
(1) 如果cancel(boolean)调用了,则执行onCancelled(Result)方法
(2) 如果cancel(boolean)没有调用,则执行onPostExecute(Result)方法
AsyncTask的cancel方法需要一个布尔值的参数,参数名为mayInterruptIfRunning,意思是如果正在执行是否可以打断,如果这个值设置为true,表示这个任务可以被打断,否则,正在执行的程序会继续执行直到完成。如果在doInBackground()方法中有一个循环操作,我们应该在循环中使用isCancelled()来判断,如果返回为true,我们应该避免执行后续无用的循环操作。
总之,我们使用AsyncTask,需要确保AsyncTask正确地取消。
上面的内容主要参考了: Android中糟糕的AsyncTask 这篇技术博客, 我记得在任玉刚的《Android开发艺术探索》这本书时候也讲到这一点.
内存泄露
在Activity中创建AsyncTask内部类很方便,如果在Acitvity中使用非静态匿名内部类(我的代码经常会出现),非静态的内部类会持有对外部类的隐式引用. 由于AsyncTask的生命周期可能比Activity长,当Activity销毁时,AsyncTask还在执行,由于AsyncTask持有Activity的引用,会导致Acitivity无法回收,产生内存泄露.
在看android源码 (\apps\Contacts\src\com\android\contacts\util) 的时候,注意到一个google工程师写的工具类WeakAsyncTask,内部用到了WeakReference软引用,这样可以解决内存泄露的问题;
其实给AysncTask加上static,静态的内部类不会持有对外部类的引用,就能够解决问题,只不过这样如果AysncTask的方法用到的成员变量都需要加上static;
下面是WeakAsyncTask的源码:
public abstract class WeakAsyncTask<Params, Progress, Result,WeakTarget> extends AsyncTask<Params,Progress,Result> { protected WeakReference<WeakTarget> mTarget; public WeakAsyncTask(WeakTarget target) { mTarget = new WeakReference<WeakTarget>(target); } @Override protected final void onPreExecute() { final WeakTarget target = mTarget.get(); if (target != null) { this.onPreExecute(target); } } @Override protected final Result doInBackground(Params... params) { final WeakTarget target = mTarget.get(); if (target != null) { return this.doInBackground(target,params); } else { return null; } } @Override protected final void onPostExecute(Result result) { final WeakTarget target = mTarget.get(); if (target != null) { this.onPostExecute(target,result); } } protected void onPreExecute(WeakTarget target) { // No default action } protected abstract Result doInBackground(WeakTarget target, Params... params); protected void onPostExecute(WeakTarget target, Result result) { // No default action }}
很简单,用法也几乎和AsyncTask一样:
private static class MyTask extends WeakAsyncTask<Void, Void, String,MainActivity> { public MyTask(MainActivity target) { super(target); } @Override protected String doInBackground(MainActivity target, Void... params) { //获取context,执行一些操作 Context context = target; return "Hello Android !!!!!"; } @Override protected void onPostExecute(MainActivity target, String s) { //执行操作 } }
直接调用执行:
new MyTask(this).execute();
其实还可以根据这个思想写一个WeakHandler !
点击这里下载源码
- Android 防内存泄露的AsyncTask--WeakAsyncTask
- Android中AsyncTask的内存泄露
- Android之AsyncTask的内存泄露问题
- android 图片 防内存泄露
- Android 防内存泄露handler
- Android应用防内存泄露小结
- AsyncTask的深度优化(内存泄露)
- android的内存泄露
- android的内存泄露
- Android之AsyncTask异步任务——防止内存泄露
- android内存泄露的问题
- android内存泄露的问题
- android内存泄露的问题
- android内存泄露的问题
- android内存泄露的问题
- android内存泄露的问题
- Android的内存泄露测试
- Android的内存泄露测试
- Activity页面左右切换动画
- Android自定义音量条控件
- Androidx学习笔记(17)-- 数据存储之XML
- 05 IO流
- 启动模式影响android操作
- Android 防内存泄露的AsyncTask--WeakAsyncTask
- 利用七参数进行CGCS2000坐标系到西安80坐标系的转换
- python进阶——类和对象
- poj2230 Watchcow
- Java日志工具:Log4J, JCL, SLF4J
- PostgreSQL学习手册(索引)
- PDF文件中的数字签名之(在一个PDF文件的签名代表)
- 【BZOJ】1002 轮状病毒
- Mac下CocoaPods的安装及使用(最新)