Android AsyncTask 取消全部任务 , 解决内存泄漏问题

内存泄漏参考https://blog.csdn.net/womengmengyan/article/details/52315564

以下代码具备的功能: 

1. 取消当前添加的所有 AsyncTask , 尽量减少重复的网络请求任务

(场景: 我们需要在一个界面中定时每 10s 请求一次网络获取一次数据 ,我们知道网络请求时间是不固定的 ,可能很快的请求完成,也可能很慢,因此,我为了尽量节省开销,希望每次都能在指定的时间执行一次网络请求就好了)

2. 尝试解决内存泄漏问题

(内存泄漏,多是由于有些界面或对象销毁或生命周期结束后,仍然有一些引用持有该界面或对象 ,如: 想在一个已经销毁的界面中进行更新UI操作,

内存泄漏带来的影响: 随着泄漏的累积,app将消耗完内存)

3. 循环请求网络

实现定时请求网络的功能

 

代码开始 ---->>>

Activity 部分: 

public class MainActivity extends AppCompatActivity{

    private static final String TAG = "MainActivity";

    private List<String> showData = new ArrayList<>();

    private SoftHandler mHandler = new SoftHandler(this);

    private ImRunnable mImRunnable;

    private MainAdapter mAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initView();

        mImRunnable = new ImRunnable();
        mHandler.removeCallbacks(mImRunnable);//清除上一次任务的影响

        mHandler.postDelayed(mImRunnable, 300);//延时请求网络

    }

    private void initView() {

        RecyclerView rcv = (RecyclerView) findViewById(R.id.rcv);
        rcv.setLayoutManager(new GridLayoutManager(this, 4));
        mAdapter = new MainAdapter(showData);
        rcv.setAdapter(mAdapter);

    }

    //执行延时任务
    private class ImRunnable implements Runnable, OnResponseCallback {
        @Override
        public void run() {

            Log.i("NotifyService", "run: " + Thread.currentThread());

          if (NetUtils.isNeedLoading) {

                HashMap<String, String> parameters = new HashMap<>();
                parameters.put("key", "value");
                NetUtils netUtils = new NetUtils(MainActivity.this,this);
                NetUtils.putTaskFloor(netUtils);//todo 保存每次创建的 AsyncTask 对象(弱引        
                                                                用),在取消全部的时候会用到
                netUtils.execute(new TestWeb(parameters));
          }

            //重复执行本身
            mHandler.postDelayed(this, 300);

        }

        @Override
        public void onSuccess(List<String> stringList) {

            Log.i(TAG, "onSuccess: ");

            if (stringList.get(0).equals("pass")) {

                stringList.remove(0);
                showData.clear();
                showData.addAll(stringList);
                mAdapter.setData(showData);
                mAdapter.notifyDataSetChanged();

                Toast.makeText(MainActivity.this, "更新了数据!", Toast.LENGTH_SHORT).show();

            } else {

                Toast.makeText(MainActivity.this, "数据读取失败", Toast.LENGTH_SHORT).show();
            }

        }

        @Override
        public void onFail() {

            Log.i(TAG, "onFail: ");
        }
    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        
        showData.clear();
        showData = null;

        NetUtils.isNeedLoading = false;

        mHandler.removeCallbacksAndMessages(null);

        System.gc();
    }


}
public class SoftHandler extends Handler {

    //使用软引用,方便系统回收

    private final WeakReference<Activity> mActivity;

    public SoftHandler(Activity activity) {
        mActivity = new WeakReference<Activity>(activity);
    }

    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
    }

}

AsyncTask 部分:

public class NetUtils extends AsyncTask<BaseRequest, Void, List<String>> {

    public static List<WeakReference<NetUtils>> allTask = new ArrayList<>();//临时保存任务
    private WeakReference<Activity> weakAty;

    private final OnResponseCallback mOnResponseCallback;
    public static boolean isNeedLoading = true;
    public static boolean isNeedSingleTask = true;//是否需要每次只允许一个任务执行

    public NetUtils(Activity activity, OnResponseCallback onResponseCallback) {

        this.mOnResponseCallback = onResponseCallback;
        weakAty = new WeakReference<Activity>(activity);

    }

    public static void putTaskFloor(NetUtils netUtils) {

        allTask.add(new WeakReference<NetUtils>(netUtils));

    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();

    }

    @Override
    protected List<String> doInBackground(BaseRequest... voids) {

        isNeedLoading = false;

        if (isCancelled()) {
            return null;
        }

        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        Log.e("NetUtils", "doInBackground:");


        return null;

    }

    @Override
    protected void onPostExecute(List<String> stringList) {
        super.onPostExecute(stringList);

        isNeedLoading = true;

        if (isNeedSingleTask) {

            cancelAllRunningTask();//todo 拿到结果后,将再等待中的任务全部取消

        }

        Activity mActivity;

        Activity activity = mActivity = (Activity) weakAty.get();

        if (activity != null && !activity.isFinishing()) {
       
       //activity != null && !activity.isFinishing() 决定了是否继续让持有的 activity 做事
       //即只有当当前的 activity 没有 finish 的时候我们才有必要去更新UI

            if (stringList != null) {

                if (stringList.get(0).equals("pass")) {

                    if (mOnResponseCallback != null) {

                        mOnResponseCallback.onSuccess(stringList);

                    }

                } else {

                    if (mOnResponseCallback != null) {

                        mOnResponseCallback.onFail();

                    }

                }

            } else {
                if (mOnResponseCallback != null) {
                    mOnResponseCallback.onFail();
                }
            }

        }

        Log.e("NetUtils", "onPostExecute: 正在执行 AsyncTask from NetUtils");


    }

  
    public static void cancelAllRunningTask() {

        if (allTask != null && allTask.size() > 0) {

            for (int i = 0; i < allTask.size(); i++) {

                NetUtils netUtils = allTask.get(i).get();

                if (!netUtils.isCancelled()) {
                    netUtils.cancel(true);//没有取消就取消
                    Log.w("NetUtils", "cancelAll: 正在执行 AsyncTask from NetUtils");
                    allTask.remove(i);
                } else {
                    allTask.remove(i);
                }

                int size = NetUtils.allTask.size();
                Log.i("NetUtils", "cancelAllRunningTask: 取消一个任务后还有多少: "+size);

            }

        }

    }

}
public interface OnResponseCallback {
    void onSuccess(List<String> stringList);
    void onFail();

}

结束: 如果有更好的写法,请不吝赐教 [握手]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值