bikash_binay
bikash_binay

Reputation: 219

How can i cancel the AsynsTask in Android?

Hi onCancel of dialog i want to cancel to server call but i m facing problem that even i cancel the task, it hits my server and modifies the data. How can I resolve this issue ? Below is my code..


     private class UserBoardingTask extends AsyncTask {
            @Override
            protected void onPreExecute() {
                progressDialog = new ProgressDialog(getActivity());
                progressDialog.setMessage(getResources().getString(R.string.please_wait));
                progressDialog.setIndeterminate(false);
                progressDialog.setCancelable(true);
                progressDialog.setOnCancelListener(new OnCancelListener() {
                @Override
                    public void onCancel(DialogInterface dialog) {
                         if (userOnBoardingTask!= null && userOnBoardingTask.getStatus() != AsyncTask.Status.FINISHED && !userOnBoardingTask.isCancelled()) {
                             userOnBoardingTask.cancel(true);

                           }      
                    }
                });
                progressDialog.show();
            }

            @Override
            protected Void doInBackground(String... urls) {
                String boardingURL=null;


                boardingURL= getUrl();


                UserOnBoardingDTO userOnBoardingDetailsDTO = AppStateManager.getUserBoardingDetails();
                try{

                    RestAPIManager.putToNSWebService(boardingURL, userOnBoardingDetailsDTO, username, password);

                }   


                   catch (Exception e) {
                   errorMessage=getResources().getString(R.string.unknown_exp);
                    }
                return null;
                }

            @Override
            protected void onCancelled() {
                super.onCancelled();
                closeProgressDialog();
                errorMessage="";
                AppStateManager.setUserBoardingDetails(null);
                userOnBoardingTask=null;

            }

            @Override
            protected void onPostExecute(Void res) {
                closeProgressDialog();
                userOnBoardingTask=null;
                if(!FieldsValidator.isBlank(errorMessage)){
                    CommonUtil.showToast(getActivity(),errorMessage);
                    errorMessage="";
                    return; 
                }

Upvotes: 0

Views: 496

Answers (7)

user3244026
user3244026

Reputation: 41

Short Anser: Its not possible stop data posts thru a simple cancel. once an async task runs even if you cancel it mid way data posts will occure. Cancellation can be done in a Simple Run Check this Post [Android - Cancel AsyncTask Forcefully

Upvotes: 0

aurelianr
aurelianr

Reputation: 549

If you cancel the asynctask after access this method RestAPIManager.putToNSWebService(boardingURL,userOnBoardingDetailsDTO, username, password); the async task will cancel after running the above code so you should correct this by creating a new method inside RestAPIManager class and call that method inside OnCancelled method from your asyncTask.

Upvotes: 0

Mohamed Mohaideen AH
Mohamed Mohaideen AH

Reputation: 2545

RestAPIManager.putToNSWebService(boardingURL, userOnBoardingDetailsDTO, username, password);

This above code hit the server. So you have to validate the execution of code inbetween cancellation.

Try something like this

  try{
if(!userOnBoardingTask.isCancelled())
{
                RestAPIManager.putToNSWebService(boardingURL, userOnBoardingDetailsDTO, username, password);
}

            }   


               catch (Exception e) {
               errorMessage=getResources().getString(R.string.unknown_exp);
                }

This is ok. If user cancel the task before ResetAPIManager code executes. Suppose user try to cancel the task after server call initiated you have to tell already modified or remodify server data or unable to cancel or some message to user. All done through getting server reponse and validate server response if it changed or not.

Use something like this

 Var rsponse = RestAPIManager.putToNSWebService(boardingURL,userOnBoardingDetailsDTO, username, password);

Validate the reponse message in onPostExecute() or OnCancelled() method.

Upvotes: 0

Tomasz Gawel
Tomasz Gawel

Reputation: 8520

Where is userOnBoardingTask declared and where it is assigned to a reference to running task? I suspect this does not store a proper reference when the task tries to cancel it.

I am not sure if it is the actual reason of your problem. But for sure you may get rid of this variable if it is intended to pint at current task. Just change dialog's on cancel listener:

private class UserBoardingTask extends AsyncTask<String, Void, Void> {

@Override
protected void onPreExecute() {

    // ...

    progressDialog.setOnCancelListener(new OnCancelListener() {

        @Override
        public void onCancel(DialogInterface dialog) {
            if (UserBoardingTask.this.getStatus() != AsyncTask.Status.FINISHED 
                && UserBoardingTask.this.isCancelled()) {
                UserBoardingTask.this.cancel(true);
            }
        }
    });

In fact you may omit UserBoardingTask.this phrase as the inner class can point directly fields of nesting class as far as the names are not obscured by the names of inner class members:

private class UserBoardingTask extends AsyncTask<String, Void, Void> {

@Override
protected void onPreExecute() {

    // ...

    progressDialog.setOnCancelListener(new OnCancelListener() {

        @Override
        public void onCancel(DialogInterface dialog) {
            if (getStatus() != AsyncTask.Status.FINISHED && isCancelled()) {
                cancel(true);
            }
        }
    });

EDIT

Another point is that before sending request to the server you may check inside doInBackground you may check if the task has not been cancelled

        // ...

        @Override
        protected Void doInBackground(String... urls) {

            // ...

            try {
                if(isCancelled()) {
                   throw new Exception("Exit: task cancelled!");
                }

                RestAPIManager.putToNSWebService(boardingURL, userOnBoardingDetailsDTO, username, password);

            // ...

Upvotes: 0

Ajay
Ajay

Reputation: 75

Actually the problem is not termination of your asynsTask but the server hit if a server hit is already done before termination of asynsTask then you must interrupt your server request also.Just terminate your server request using abort method.

Upvotes: 0

RaphMclee
RaphMclee

Reputation: 1623

Move the dialog out of the async task and only start the task when the dialog is not canceled.

Upvotes: 0

Digvesh Patel
Digvesh Patel

Reputation: 6533

Just check isCancelled() once in a while:

 protected Object doInBackground(Object... x) {
    while (/* condition */) {
      // work...
      if (isCancelled()) break;
    }
    return null;
 }

and another solution is

protected void onProgressUpdate(String... progress1) {
                         if(condition){

                                break;
                        }
        }

Upvotes: 2

Related Questions