User12111111
User12111111

Reputation: 1219

Android: Back button press while AsyncTask is running

I have an ActivityA, which has a Button. Upon Click on the button, it opens up another ActivityB.

onCreate() method of ActivityB, I am starting AsyncTask which connect to server and fetch the results and display it to the screen.

Here is the Code of Activity B:

public class ActivityB extends Activity {
    AsyncFetch asyncFetch;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if(null != savedInstanceState) {
            return;
        }
        asyncFetch = new AsyncFetch();
        asyncFetch.execute();
    }
}


private class AsyncFetch extends AsyncTask<Object, Void, Object> {
    @Override
    protected void onPostExecute(Object o) {

    }

    @Override
    protected Object doInBackground(Object... params) {
        //contacts the http server.
    }
}

While executing AsyncFetch, when I hit back press, the ActivityB is not getting destroyed immediately. But gets destroyed after AsyncTask gets completed.

How do I implement this to avoid back press freeze? I tried below:

@Override
protected void onDestroy() {
    asyncFetch.cancel(true);
    super.onDestroy();
}

But still it waits the AsyncTask to cancel or complete.

Like GMail app, when I open something. While in the process if I press back button, it just comes out of that Activity.

Is there any other way of implementing background process? Any design pattern to implement this? Please let me know.

Any help is appreciated.

Upvotes: 8

Views: 7535

Answers (5)

Endor
Endor

Reputation: 394

From the android developer's website:

Cancelling a task

A task can be cancelled at any time by invoking cancel(boolean). Invoking this method will cause subsequent calls to isCancelled() to return true. After invoking this method, onCancelled(Object), instead of onPostExecute(Object) will be invoked after doInBackground(Object[]) returns. To ensure that a task is cancelled as quickly as possible, you should always check the return value of isCancelled() periodically from doInBackground(Object[]), if possible (inside a loop for instance.)

So in short, you can mark the AsyncTask as cancelled in onPause() or onBackPressed() from your Activity, and then you can add a few if blocks in doInBackground() and return right away if task is cancelled.

For example:

@Override
protected void doInBackground(Object... params){

    // do some work

    if(isCancelled()){
        // end task right away
        return null;
    }
    // if task is not cancelled yet,
    // do some other work
}

However, if the network operation has already started, you will need to cancel it from your HttpClient.

Upvotes: 3

jtxyz0804
jtxyz0804

Reputation: 54

When you click the back button, it will firstly called onBackPressed(), so in this part, cancel the asynctask.

@Override
public void onBackPressed() {
    if ( asyncFetch != null && asyncFetch.getStatus() == AsyncTask.Status.RUNNING ){
       asyncFetch.cancel(true);
    } 
}

Upvotes: -1

Remees M Syde
Remees M Syde

Reputation: 2609

Here we go. Try this.

@Override
public void onBackPressed() {
    if (asyncFetch.getStatus() == AsyncTask.Status.RUNNING) {
       asyncFetch.cancel(true);
    } 
    finish(); 
}

Upvotes: 1

Alex
Alex

Reputation: 191

Just handle yourself the onBackPressed() method:

@Override
public void onBackPressed()
{
    if (asyncFetch != null)
        asyncFetch.cancel(true);

    super.onBackPressed();
}

Upvotes: 4

Batuhan Coşkun
Batuhan Coşkun

Reputation: 2969

Try this:

@Override
public void onBackPressed() {
    asyncFetch.cancel(true);
    // If you want to finish the activity you can use below code
    // finish(); 
}

Upvotes: 2

Related Questions