我在这里阅读了一些问题,浏览了一些互联网文章,但是关于AsyncTask中的内存泄漏问题并不清楚。请问您能给我一些建议吗?
让我们考虑一些情况:
1)AsyncTask是一个内部类
我编写了MyAsyncTask来从服务器下载小数据(<1 KB),并将其写入MyActivity代码中(而不是作为静态类)。它将存储对MyActivity实例的隐式引用。如果我开始执行MyAsyncTask.execute(),那么直到此AsyncTask完成之前,MyActivity实例将无法进行垃圾回收。因此,如果我在AsyncTask执行期间旋转屏幕,则旧的MyActivity实例将会在内存中 - 这就是内存泄漏。
我的解决方案是:由于要下载的数据很小,所以我将在MyActivity的onDestroy()方法中取消MyAsyncTask。这样,我有如下MyActivity代码:
public class MyActivity extends Activity {
//views and constants
private MyAsyncTask air;
private ProgressDialog progressDialog;
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.account_info_layout);
progressDialog = new ProgressDialog(this);
//findViewById, etc.
}
@Override
protected void onStart() {
super.onStart();
air = new MyAsyncTask();
air.execute();
}
@Override
protected void onDestroy() {
if (air.getStatus() == AsyncTask.Status.RUNNING) {
air.cancel(true);
}
air = null;
super.onDestroy();
}
class MyAsyncTask extends AsyncTask<Void, Void, String> {
@Override
protected void onPreExecute() {
super.onPreExecute();
UserData.refreshTimer();
if (!progressDialog.isShowing())
progressDialog.show();
}
@Override
protected String doInBackground(Void... params) {
//GET request
return result;
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
//handle results
progressDialog.dismiss();
}
}
}
那么,如果我的活动实例被销毁,我会取消异步任务,并在onStart()中创建新的实例。这会产生内存泄漏吗?或者由于progressDialog实例,它会产生IllegalArgumentException/NullPointerException吗?我认为不会产生任何异常,因为如果我取消了AsyncTask,则不会调用onPostExecute()。
2) 在自己的文件中使用AsyncTask
下一个情况是当我在其他文件中编写MyAsyncTask,并在构造函数中传递Context实例。如果我将Context作为WeakReference存储,这种方法会导致内存泄漏吗?在调用Activity中的onDestroy()方法中取消AsyncTask是正确的想法,以避免在onPostExecute()方法期间出现IllegalArgumentException/NullPointerException吗?或者,避免这些异常的另一种方法是检查我的Context变量是否为null。
其他方法:我听说过Otto库,关于使用保留的Fragment,但现在我想理解这些问题。如果有人知道,请回答。