Reputation: 219
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
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
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
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
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
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
Reputation: 1623
Move the dialog out of the async task and only start the task when the dialog is not canceled.
Upvotes: 0
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