AsyncTask [Memory leaks]

AsyncTask [Memory leaks]

https://medium.com/@akhilgupta.me/asynctask-memory-leaks-170f4a21b16f

This post is part continuation of Memory Leaks in Android

For any work which needs to be done of UI thread, we do have many choices for that AsyncTask is one of them. Its pretty straight forward to use. Below is excerpt from developer.android.com

AsyncTask enables proper and easy use of the UI thread. This class allows to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers.
AsyncTask is designed to be a helper class around  Thread and  Handler and does not constitute a generic threading framework. AsyncTasks should ideally be used for short operations (a few seconds at the most.) If you need to keep threads running for long periods of time, it is highly recommended you use the various APIs provided by the  java.util.concurrent package such as  ExecutorThreadPoolExecutor and  FutureTask.
An asynchronous task is defined by a computation that runs on a background thread and whose result is published on the UI thread. An asynchronous task is defined by 3 generic types, called  ParamsProgress and  Result, and 4 steps, called  onPreExecutedoInBackgroundonProgressUpdate and onPostExecute.

But if we do not use it proper way, it can cause memory leaks in app. Consider below example.

private void updateProgressAsyncTask() {
    mProgressAsyncTask=new AsyncTask<Void, Integer, Void>() {
        @Override
        protected Void doInBackground(Void... voids) {
            for (int i = 0; i < AppConstants.LOOP_COUNT; i++) {
                    try {
                        Thread.sleep(AppConstants.THREAD_SLEEP_TIME);
                        progressCount++;
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    publishProgress(progressCount);
            }
            return null;
        }

        @Override
        protected void onProgressUpdate(Integer... values) {
            super.onProgressUpdate(values);
            updateCounter(values[0]);
        }
    }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}

Problem:

You can see in below gif, how this perfectly looking AsyncTask is causing memory leak, Which is getting detected via awesome LeakCanary lib.

Wondering, how it happened ? Its simple that as soon as we pressed back button, activity gets destroyed. But AsyncTask continues to run and it holds reference to our activity.

Solution:

its not hard, just remember to cancel AsyncTask in activity’s onDestory() method. Though there is one catch that AsyncTask’s cancel() method doesn’t stop and can’t stop the running background thread itself, though it can help you stop processing background thread. cancel() method does set a flag, using which you can stop processing in background thread. Here is updated code snippet

private void updateProgressAsyncTask() {
    mProgressAsyncTask=new AsyncTask<Void, Integer, Void>() {
        @Override
        protected Void doInBackground(Void... voids) {
            for (int i = 0; i < AppConstants.LOOP_COUNT; i++) {
                if (!isCancelled()) {//check that if canceled or not
                    try {
                        Thread.sleep(AppConstants.THREAD_SLEEP_TIME);
                        progressCount++;
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    publishProgress(progressCount);
                }
            }
            return null;
        }

        @Override
        protected void onProgressUpdate(Integer... values) {
            super.onProgressUpdate(values);
            updateCounter(values[0]);
        }
    }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}

@Override
protected void onDestroy() {
    super.onDestroy();
    if(mProgressAsyncTask!=null)//cancel asynctask
        mProgressAsyncTask.cancel(true);
}

And here is GIF with solution applied:)

So here LeakCanary didn’t detected any memory leak, Awesome:) isn’t it ?


Other posts in series:

  1. Memory Leaks in Android
  2. Handlers [Memory Leaks]
  3. Static -[Memory Leaks]

猜你喜欢

转载自blog.csdn.net/ultrapro/article/details/84632783