简体   繁体   中英

Does starting an AsyncTask inside onResume method does cost more memory?

I use AsyncTask to update list from local database(sqlite) as the following :

 @Override
    public void onResume() {
        super.onResume();
       new MyAsynctask().execute();

    }

I need a clear explanation what happen every time when new MyAsynctask execute and what happen to the previous MyAsynctask that was created earlier, and if this way cost more memory?

Your new async task does nothing.

AsyncTasks are executed after each other.

Only when your old async task ends the new one will start running.

AsyncTask is just a implementation of thread to manage Background task and UI updation . AsyncTask is designed to be a helper class around Thread and Handler in android .From the documentation .

AsyncTask enables proper and easy use of the UI thread. This class allows you to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers.

So for your question each time you call new MyAsynctask().execute(); A new thread will starts . And the older one will run also if not finished .

To cancel previous task you can use a global instance of task and check if status is RUNNING by getStatus()

 if(asyncTask!=null && asyncTask.getStatus()== AsyncTask.Status.RUNNING){
            asyncTask.cancel(true);
        }

In your case you create new task in onResume() so each time your activity resumes new thread will created and this is not memory efficient solution to refresh screen.
For more detail on cancel task read Section Cancelling a task and cancel(boolean) .

If you know how to manage it, then it's not a memory leak.

Your AsyncTask will be executed inside the onResume() function, thus it will run when:

  1. Every-time the Activity is (re)created
  2. You come back from another Activity
  3. You change screen orientantion
  4. You come back from another Application started by an Intent
  5. You close and re-open your App
  6. ...

You might want to keep a class field for your AsyncTask and instantiate it in onCreate() :

private MyAsyncTask asyncTask;

In case the Activty is not destroyed (points: 1, 2 (maybe), 4(maybe), 5(maybe)), you can easily check the asyncTask status and cancel it if needed.

The problem is that the old AsyncTask might still be running when you start a new one if the Activity was re-created. And since the Activity instance is new, the asyncTask reference will point to a new Object as well : in that case you will have a savage Thread running in the background.

Unless Android 's OS kills Activity 's owned Thread (not sure about that) , you might still get away by knowing and making sure that your AsyncTask will run for a few seconds at most, without performing any blocking IO operation. But this isn't really an engineered solution.


I'd say, the best and more standard-compliant solution is: by keeping the reference to the AsyncTask in your Activity , just call asyncTask.cancel() in your onPause() method. And you'll be sure that the AsyncTask 's thread will be canceled before your Activity is either paused or destroyed.

Your code will then look like this:

private MyAsyncTask asyncTask;

protected void onCreate() {
    this.asyncTask = new MyAsyncTask();
}

protected void onResume() {
    this.asyncTask.execute();
}

protected void onPause() {
    this.asyncTask.cancel();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM