Cancel AsyncTask and the ProgressDialog when pressing back button on Android

1

I have a AsyncTask that launches a ProgressDialog in modal form, that can not be canceled.

In the onPreExecute start the progressDialog

progress = ProgressDialog.show(MainActivity.this, "titulo","progreso x", true);

and the asyncTask started with:

new initMap().execute();

What I try to do during the upload, if you press the back button, stop the asyncTask task, close the dialog and exit activity .

    
asked by Webserveis 31.05.2017 в 22:04
source

3 answers

3

Within the class MainActivity creates the attributes:

private Task task;
private ProgressDialog progress;

Create a subclass within MainActivity that inherits from AsyncTask , for example:

private class Task extends AsyncTask<Void, Void, Void>{
@Override protected void onPostExecute() {
 progress.dismiss();
}

@Override protected void onPreExecute() {
 progress = ProgressDialog.show(MainActivity.this, "titulo","progreso x", true);
}

@Override protected void doInBackground() {
    for(int i = 0; i<60; i++){
        if(!isCancelled()) {
            Thread.sleep(1000);
            } else break;
    }
}

}

Execute asyncTask like this:

task = (Task) new Task().execute();

Then reimplement the method onKeyDown in the MainActivity and add the code to cancel the asynctask when you press back:

@Override public boolean onKeyDown(int keyCode, KeyEvent event) {
    if(keyCode == KeyEvent.KEYCODE_BACK){
       if(task != null && task.getStatus() != AsyncTask.Status.FINISHED){
          task.cancel(true);
          progress.dismiss();
        }
    }
    return super.onKeyDown(keyCode, event);
}
    
answered by 31.05.2017 / 22:42
source
1

Thanks to the publication of the companion @Michel_Escalante_Alvarez I have adapted its code to what I have been found by SO.

Creating cancelable ProgressDialog '

To create a ProgressDialog that can be canceled by pressing the physical / virtual button at the back, but avoiding that if it is pressed outside the dialog it will not close.

progress.setCancelable(true);
progress.setCanceledOnTouchOutside(false);

and when canceling the dialogue it is intercepted with

progress.setOnCancelListener(...) 

To cancel the asyncTask

cancel(false);

Entire code of the creation of the dialogue:

@Override
protected void onPreExecute() {
    super.onPreExecute();
    //Show dialog bar
    progress = new ProgressDialog(MainActivity.this);
    progress.setTitle("titulo");
    progress.setMessage("progreso x");
    progress.setCancelable(true);
    progress.setCanceledOnTouchOutside(false);
    progress.setOnCancelListener(new DialogInterface.OnCancelListener() {
        @Override
        public void onCancel(DialogInterface dialog) {
            cancel(false); //se cancela el asyntask
        }
    });
    progress.show();
}

Driver when canceling the task

In the event doInBackground with the function isCancelled can be obtained if you need to cancel.

@Override
protected Boolean doInBackground(Void... voids) {
    if (!isCancelled()) {
     //seguir la tarea
    } return false;
    return true;
 }

Completely complete the task

When the task is finished correctly or has been canceled, the event onPostExecute

is computed
@Override
protected void onPostExecute(Boolean result) {
    super.onPostExecute(result);

    if (result) {
        progress.dismiss();
        Log.i(TAG, "onPostExecute: Finalizado correctamente" );
    } else {
        Log.w(TAG, "onPostExecute: Cancelación por parte del usuario");
    }
}

Capture the cancellation

You can intercept the event before canceling with onCancelled

@Override
protected void onCancelled(Boolean aBoolean) {
    super.onCancelled(aBoolean);
    Log.w(TAG, "onCancelled: " + aBoolean );
}
    
answered by 31.05.2017 в 23:11
1

In this case it detects the "back" event and cancels the AsyncTask and Dialog:

@Override public boolean onKeyDown(int keyCode, KeyEvent event) {
    if(keyCode == KeyEvent.KEYCODE_BACK){
       if(initMap!= null && task.getStatus() != AsyncTask.Status.FINISHED){

          //Cancela el AsynckTast.
          initMap.cancel(true);
          //Cancela el ProgressDialog.
          progress.dismiss();

          //Puedes usar finish() si te encuentras dentro de la Activity.
          //finish();


        }
    }
    return super.onKeyDown(keyCode, event);
}

Using the cancel (true) method ensures that the Asynctask is finished even if the task has not been completed, otherwise you can use cancel (false)

    
answered by 31.05.2017 в 23:06