在我的应用程序中,我有一个异步任务,它将从远程服务器下载文件。
在该课程中,我设置了一个具有取消按钮的ProgressDialog。如果我只使用一次异步任务并创建AsyncTask实例,可能会更容易。
我可以像我在一些样本上看到的那样打电话给asyncTask.cancel(true)
。
但在我的Activity中,我已多次执行AsyncTask:
new MyAsynTask().execute(url_of_file_1);
new MyAsynTask().execute(url_of_file_2);
new MyAsynTask().execute(url_of_file_3);
虽然这不完全是结构,但感觉是这样的。
这就是MyAsyncTask
的样子:
private class MyAsyncTask extends AsyncTask<String, Integer, String> {
ProgressDialog pdialog;
@Override
protected void onPreExecute() {
super.onPreExecute();
if(!MyActivity.this.isFinishing()){
mProgressDialog = new ProgressDialog(MyActivity.this);
mProgressDialog.setCancelable(false);
mProgressDialog.setButton(DialogInterface.BUTTON_POSITIVE, "Cancel", new CancelOnClickListener());
}
}
@Override
protected String doInBackground(String... fileUrl) {
try {
//do connection to url things
if(!isCancelled()){
// download the file
}else{
pdialog.dismiss();
mProgressDialog.dismiss();
}
}catch(MalformedURLException e){
}catch(FileNotFoundException e){
}catch(Exception e){
}
return null;
}
@Override
protected void onProgressUpdate(Integer... values) {
if(!MyActivity.this.isFinishing()){
mProgressDialog.setMessage("Downloading..." + values[0]);
mProgressDialog.show();
super.onProgressUpdate(values);
}
}
@Override
protected void onPostExecute(String result) {
if(!MyActivity.this.isFinishing()){
super.onPostExecute(result);
mProgressDialog.dismiss();
}
}
private final class CancelOnClickListener implements DialogInterface.OnClickListener {
public void onClick(DialogInterface dialog, int which) {
new MyAsyncTask().cancel(true); // is this correct?
MyActivity.this.finish();
try {
MyActivity.this.finalize();
} catch (Throwable e) {
application.shortToast("Error encountered in closing the page");
}
// maybe i should call super.onBackPressed();
application.shortToast("Download Cancelled");
}
}
}
当我按下取消时发生的事情是它总是有这个例外,但我的应用程序有时不会崩溃...
08-14 23:07:12.702: E/WindowManager(8623): Activity com.android.app.MyActivityhas leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@43f7c938 that was originally added here
08-14 23:07:12.702: E/WindowManager(8623): android.view.WindowLeaked: Activity com.android.app.MyActivityhas leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@43f7c938 that was originally added here
08-14 23:07:12.702: E/WindowManager(8623): at android.view.ViewRootImpl.<init>(ViewRootImpl.java:384)
08-14 23:07:12.702: E/WindowManager(8623): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:292)
08-14 23:07:12.702: E/WindowManager(8623): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:224)
08-14 23:07:12.702: E/WindowManager(8623): at android.view.WindowManagerImpl$CompatModeWrapper.addView(WindowManagerImpl.java:149)
08-14 23:07:12.702: E/WindowManager(8623): at android.view.Window$LocalWindowManager.addView(Window.java:547)
08-14 23:07:12.702: E/WindowManager(8623): at android.app.Dialog.show(Dialog.java:285)
08-14 23:07:12.702: E/WindowManager(8623): at com.android.app.MyActivity$MyAsyncTask.onPreExecute(PartsActivity.java:784)
08-14 23:07:12.702: E/WindowManager(8623): at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:586)
08-14 23:07:12.702: E/WindowManager(8623): at android.os.AsyncTask.execute(AsyncTask.java:534)
08-14 23:07:12.702: E/WindowManager(8623): at com.android.app.MyActivity$SecondAsyncTask.onPostExecute(PartsActivity.java:980)
08-14 23:07:12.702: E/WindowManager(8623): at com.android.app.MyActivity$SecondAsyncTask.onPostExecute(PartsActivity.java:1)
08-14 23:07:12.702: E/WindowManager(8623): at android.os.AsyncTask.finish(AsyncTask.java:631)
08-14 23:07:12.702: E/WindowManager(8623): at android.os.AsyncTask.access$600(AsyncTask.java:177)
08-14 23:07:12.702: E/WindowManager(8623): at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644)
。 。 。 。
那么当我按下ProgressDialog中的取消按钮时,结束那些被执行的AysnTask的正确方法是什么?
答案 0 :(得分:1)
保留每项任务的参考:
MyAsynTask task1 = new MyAsynTask();
task1.execute(url_of_file_1);
由于您的异常具有其他性质,因此当您单击取消按钮(即事件线程,而不是后台线程)时,需要关闭该对话框。
在“取消”按钮回调中:
myDialog.dissmiss()
task1.cancel(true);