2

I am trying to cancel/end an async task on the button click of a pop-up box. However, when I click on the button the onCancelled() method is not being called. Could someone please help me with this? Below is my code:

public AuthenticationAsync(Context context, final String rid) {
    this.rid = rid;

    alertDialog = new AlertDialog.Builder(context).create();
    alertDialog.setTitle("Information");
    alertDialog.setMessage("RaspberryPi Validated");
    alertDialog.setButton(AlertDialog.BUTTON_NEUTRAL, "OK",
            new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    cancel(true); //Cancelling async task on button click
                    dialog.dismiss();
                }
            });
}


@Override
protected Object doInBackground(Object[] params) {
    String metricData = String.valueOf(kuraPayload.getMetric("data"));
    if (metricData.isEmpty()) 
        subResponse = false;
}

@Override
protected void onCancelled() {
    Log.d("Async","cancelled");  //not being called
}

@Override
protected void onPostExecute(Object o) {
    if (subResponse) {
        asyncHttpClient = new AsyncHttpClient();
        asyncHttpClient.get(WSConstants.ADD_RPI_WS + MQTTFactory.getRaspberryPiById(), new AsyncHttpResponseHandler() {

            @Override
            public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
                Toast.makeText(ActivityContexts.getMainActivityContext(), "RaspberryPi Validated", Toast.LENGTH_LONG).show();
                alertDialog.show();
            }

    } 
}
}
aries
  • 849
  • 3
  • 11
  • 24

2 Answers2

1

It looks like the it's never getting into onCancelled() because you are actually calling alertDialog.show() in onPostExecute(). Since doInBackground() has already completed, there is nothing to cancel.

The cancel() method is meant to be called during the execution of the doInBackground() method, which is the only method that runs on a background Thread.

Note that even if cancel() is called during execution of doInBackground(), the execution of the method won't be stopped immediately. You should do periodic checks to isCancelled() and if it returns true, then exit out of the method.

After doInBackground() has completed, if cancel() has been called, then onCancelled() will be called instead of onPostExecute().

Here is a very simple test based on your code:

public class AuthenticationAsync extends AsyncTask {

    AlertDialog alertDialog;
    String rid;

    public AuthenticationAsync(Context context, final String rid) {
        this.rid = rid;

        alertDialog = new AlertDialog.Builder(context).create();
        alertDialog.setTitle("Information");
        alertDialog.setMessage("RaspberryPi Validated");
        alertDialog.setButton(AlertDialog.BUTTON_NEUTRAL, "OK",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        cancel(true); //Cancelling async task on button click
                        dialog.dismiss();
                    }
                });
    }

    @Override
    protected void onPreExecute(){
        //for testing, showing the dialog before the background Thread starts
        alertDialog.show();
    }

    @Override
    protected Object doInBackground(Object[] params) {
       //cycle forever until the user clicks OK
       while (true){
           try {
               Thread.sleep(1000);
           } catch (InterruptedException e) {
               e.printStackTrace();
           }
           //Check if user clicked OK in the dialog
           if (isCancelled()){
               //Exit the method if the user dismissed the dialog
               return null;
           }
       }
    }

    @Override
    protected void onCancelled() {
        Log.d("Async", "cancelled");  //this is called now
        Toast.makeText(MainActivity.this, "cancelled", Toast.LENGTH_LONG).show();
    }

    @Override
    protected void onPostExecute(Object o) {
        Toast.makeText(MainActivity.this, "postExecute", Toast.LENGTH_LONG).show();
    }
}

Result:

Dialog is shown during execution of doInBackground():

dialog shown

After clicking OK, onCancelled() is called:

onCancelled

Daniel Nugent
  • 43,104
  • 15
  • 109
  • 137
0

@yanchenko answered something similar there -> Ideal way to cancel an executing AsyncTask

You can use one ProgressDialog and set this dialog as Cancelable and set the CancelListener.

Community
  • 1
  • 1
Thiago Souto
  • 761
  • 5
  • 13