0

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; 
                }

bikash_binay
  • 219
  • 3
  • 12

7 Answers7

2

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;
                        }
        }
Digvesh Patel
  • 6,503
  • 1
  • 20
  • 34
0

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

RaphMclee
  • 1,623
  • 13
  • 16
0

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);

            // ...
Tomasz Gawel
  • 8,379
  • 4
  • 36
  • 61
  • I have declared AsyncTask reference as private static UserOnBoardingTask userOnBoardingTask; variable in my Fragment and on button Click instantiating it. – bikash_binay Jan 22 '14 at 09:42
  • If it is staic than it is not instance variable :). Where is it assigned reference to running task? – Tomasz Gawel Jan 22 '14 at 09:43
  • Can you show the code - with some "context code" around it :) – Tomasz Gawel Jan 22 '14 at 09:45
  • private static NorthStarUserOnBoardingTask userOnBoardingTask; //in frgagment and on button click calling userOnBoardingTask=new NorthStarUserOnBoardingTask(); userOnBoardingTask.execute(); – bikash_binay Jan 22 '14 at 09:50
  • Ok so it seems that my proposal is not the solution to your problem, but anyway you may take it to make your code "cleaner". – Tomasz Gawel Jan 22 '14 at 09:54
0

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.

Ajay
  • 75
  • 7
  • unless there are some communications problems, request will be sent and probably delivered long befor `AsyncTask.cancel` will get called - at least that is not very predictable behaviour. Anyway calling abort() is good idea, depending on whats inside `RestAPIManager` implementation. – marcinj Jan 22 '14 at 09:43
0
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.

Mohamed Mohaideen AH
  • 2,527
  • 1
  • 16
  • 24
0

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.

aurelianr
  • 538
  • 2
  • 12
  • 35
0

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