Android AsyncTask内存泄漏警告:AsyncTaskUploadClass如何用弱引用修复
问题根因
你当前定义的AsyncTaskUploadClass是方法内的非静态内部类,默认会持有外部UploadActivity的强引用。如果上传任务未执行完成时Activity就被销毁,这个强引用会导致Activity无法被垃圾回收器回收,从而引发内存泄漏,这就是系统弹出警告的原因。
解决方案
核心思路是将AsyncTask改为静态内部类,通过弱引用持有Activity实例,同时通过构造方法传入所有需要的参数,避免直接引用外部类的变量:
- 首先将AsyncTask从方法内移出,改为Activity的静态内部类,添加弱引用持有逻辑,通过构造方法接收所需参数
// 定义为Activity的静态内部类 private static class AsyncTaskUploadClass extends AsyncTask<Void,Void,String> { // 弱引用持有Activity,避免强引用导致内存泄漏 private final WeakReference<UploadActivity> activityWeakReference; private final String imageName; private final String userName; private final String imageBase64; private ProgressDialog progressDialog; // 构造方法传入所有需要用到的参数 public AsyncTaskUploadClass(UploadActivity activity, String imageName, String userName, String imageBase64) { this.activityWeakReference = new WeakReference<>(activity); this.imageName = imageName; this.userName = userName; this.imageBase64 = imageBase64; } @Override protected void onPreExecute() { super.onPreExecute(); UploadActivity activity = activityWeakReference.get(); // 操作UI前先判断Activity是否存活,不存活直接取消任务 if (activity == null || activity.isFinishing() || activity.isDestroyed()) { cancel(true); return; } progressDialog = ProgressDialog.show(activity,"数据正在上传中....",false,false); } @Override protected void onPostExecute(String result) { super.onPostExecute(result); UploadActivity activity = activityWeakReference.get(); if (activity == null || activity.isFinishing() || activity.isDestroyed()) { return; } if (progressDialog != null && progressDialog.isShowing()) { progressDialog.dismiss(); } // 如需处理上传结果,可调用activity的公共方法处理 // activity.handleUploadResult(result); } @Override protected String doInBackground(Void... params) { if (isCancelled()) { return null; } ImageProcessClass imageProcessClass = new ImageProcessClass(); HashMap<String,String> HashMapParams = new HashMap<>(); HashMapParams.put(ImageName1, imageName); HashMapParams.put(UserName, userName); HashMapParams.put(ImagePath1, imageBase64); return imageProcessClass.ImageHttpRequest(ServerUploadPath, HashMapParams); } }
- 调整原来的触发方法逻辑
public void ImageUploadToServerFunction(){ String imageName1 = GetImageNameEditText1.trim(); String userName = GetUserName.trim(); String imageView1 = getStringImage1(bitmap1); AsyncTaskUploadClass uploadTask = new AsyncTaskUploadClass(this, imageName1, userName, imageView1); uploadTask.execute(); // 建议将uploadTask存为Activity的成员变量,方便后续取消任务 // mCurrentUploadTask = uploadTask; }
额外优化建议
- 重写Activity的
onDestroy生命周期方法,调用mCurrentUploadTask.cancel(true)取消未完成的上传任务,避免资源浪费 - 所有涉及UI操作的逻辑都要先校验弱引用获取到的Activity是否存活,避免空指针异常
内容的提问来源于stack exchange,提问作者shinsky Paul
相关产品推荐
相关产品推荐

