尽管 AsyncTask 不应该用于长时间运行的操作,但有时它可能会被不响应的任务(例如不响应的 HTTP 调用)捕获。在这种情况下,可能需要取消 AsyncTask。
我们必须在这样做时面临挑战。
1. AsyncTask 显示的通常进度对话框是用户按下后退按钮时在 AsyncTask 上取消的第一件事。
2.AsyncTask可能在doInBackground方法中
通过在 ProgressDialog 上创建dismissDialogListerner,用户可以按下后退按钮并实际取消 AsycnTask 并关闭对话框本身。
这是一个例子:
public void openMainLobbyDoor(String username, String password){
if(mOpenDoorAsyncTask == null){
mOpenDoorAsyncTask = (OpenMainDoor) new OpenMainDoor(username, password, Posts.API_URL,
mContext, "Please wait while I unlock the front door for you!").execute(null, null, null);
}
}
private class OpenMainDoor extends AsyncTask<Void, Void, Void>{
//declare needed variables
String username, password, url, loadingMessage;
int userValidated;
boolean canConfigure;
Context context;
ProgressDialog progressDialog;
public OpenMainDoor(String username, String password, String url,
Context context, String loadingMessage){
userValidated = 0;
this.username = username;
this.password = password;
this.url = url;
this.context = context;
this.loadingMessage = loadingMessage;
}
/**
* used to cancel dialog on configuration changes
* @param canConfigure
*/
public void canConfigureDialog(boolean canConfigure){
this.canConfigure = canConfigure;
}
@Override
protected void onPreExecute(){
progressDialog = new ProgressDialog(this.context);
progressDialog.setMessage(loadingMessage);
progressDialog.setIndeterminate(true);
progressDialog.setCancelable(true);
progressDialog.setOnCancelListener(new OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
mOpenDoorAsyncTask.cancel(true);
}
});
progressDialog.show();
this.canConfigure = true;
}
@Override
protected Void doInBackground(Void... params) {
userValidated = Posts.authenticateNTLMUserLogin(username, password, url, context);
while(userValidated == 0){
if(isCancelled()){
break;
}
}
return null;
}
@Override
protected void onPostExecute(Void unused){
//determine if this is still attached to window
if(canConfigure)
progressDialog.dismiss();
if(userValidated == 1){
saveLoginValues(username, password, true);
Toast.makeText(context, R.string.main_login_pass, Toast.LENGTH_SHORT).show();
}else{
saveLoginValues(username, password, false);
Toast.makeText(context, R.string.main_login_fail, Toast.LENGTH_SHORT).show();
}
nullifyAsyncTask();
}
@Override
protected void onCancelled(){
Toast.makeText(context, "Open door request cancelled!", Toast.LENGTH_SHORT).show();
nullifyAsyncTask();
}
}