2

This is my download class in which I used Asynctask.Everything works fine, when the file is downloaded fully,it shows 'file downloaded' and on 'ok' press goes back to previous activity.Now I wanted to cancel the asynctask(pls not that 'cancel asynctask' and not only the 'loading' dialogue)on back button press and go back to previous activity.How to do that?someone please help.Thanks in advance

public class Download extends Activity {

public static final int DIALOG_DOWNLOAD_PROGRESS = 0;

private ProgressDialog mProgressDialog;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.down);

    startDownload();


}

private void startDownload() {
    String url = data.proj;


    new DownloadFileAsync().execute(url);
}
private void showMsg() {
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setMessage("Document is downloaded")
           .setCancelable(false)
           .setPositiveButton("OK", new DialogInterface.OnClickListener() {
               @Override
            public void onClick(DialogInterface dialog, int id) {
                    //do things
                   Download.this.finish();
               }
           });
    AlertDialog alert = builder.create();
    alert.show();
}
@Override
protected Dialog onCreateDialog(int id) {
    switch (id) {
    case DIALOG_DOWNLOAD_PROGRESS:
        mProgressDialog = new ProgressDialog(this);
        mProgressDialog.setMessage("Downloading file..");
        mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        mProgressDialog.setCancelable(false);

        mProgressDialog.show();


        return mProgressDialog;
    default:
        return null;
    }
}

    class DownloadFileAsync extends AsyncTask<String, String, String> {

@Override
protected void onPreExecute() {
    super.onPreExecute();
    showDialog(DIALOG_DOWNLOAD_PROGRESS);

}

@Override
protected String doInBackground(String... aurl) {
    int count;

try {

URL url = new URL(aurl[0]);
URLConnection conexion = url.openConnection();
conexion.connect();

int lenghtOfFile = conexion.getContentLength();
Log.d("ANDRO_ASYNC", "Lenght of file: " + lenghtOfFile);

String fname;
 fname = data.proj.substring( data.proj.lastIndexOf('/')+1, data.proj.length() );

InputStream input = new BufferedInputStream(url.openStream());
String path=Environment.getExternalStorageDirectory()
        .toString() + File.separator;
OutputStream output = new FileOutputStream(path+fname);


byte data[] = new byte[1024];

long total = 0;

    while ((count = input.read(data)) != -1) {
        total += count;
        publishProgress(""+(int)((total*100)/lenghtOfFile));
        output.write(data, 0, count);
    }

    output.flush();
    output.close();
    input.close();
} catch (Exception e) {}

return null;

}
@Override
protected void onProgressUpdate(String... progress) {
     Log.d("ANDRO_ASYNC",progress[0]);
     mProgressDialog.setProgress(Integer.parseInt(progress[0]));
}

@Override
protected void onPostExecute(String unused) {
    dismissDialog(DIALOG_DOWNLOAD_PROGRESS);
    showMsg();
}
}}
4

2 回答 2

3

确实是老问题,但似乎很多人在取消 AsyncTasks 时仍然面临问题。所以,这里...

您将需要 AsyncTask 类 (DownloadFileAsync) 中的一个字段来存储用于取消任务的视图(此处为 ProgressDialog)。

对于 ProgressDialog,在创建对话框时,传递truesetCancelable()

mProgressDialog.setCancelable(true);

要传递视图,请更改对 Task 的调用,如下所示:

new DownloadFileAsync(mProgressDialog).execute(url);

在我们的 AsyncTask 类中,创建一个构造函数,将这个值保存到一个字段并注册一个AsyncTask 的OnCancelListener调用cancel方法:

ProgressDialog mProgressDialog;

DownloadFileAsync(ProgressDialog progressDialog) {
    mProgressDialog = progressDialog;
    mprogressDialog.setOnCancelListener(new OnCancelListener() {
        @Override
        public void onCancel(DialogInterface dialog) {
            cancel(true);
        }
    });
}

在您的 while 循环中,doInBackground循环中添加以下代码:

if (isCancelled()) {
    outputStream.flush();
    outputStream.close();
    inputStream.close();
    return null;
}

这样我们每隔一段时间就会检查任务是否被取消,如果是,我们关闭打开的流并停止运行任务并返回(返回将是任务结果的类型)。接下来,在onCancelled

@Override
protected void onCancelled (Integer fileSize) {
    super.onCancelled(fileSize);
    Log.d("TASK TAG", "Cancelled.");
    //anything else you want to do after the task was cancelled, maybe delete the incomplete download.
}
于 2014-05-27T11:07:40.783 回答
0

我就是这样

public class downloadAllFeeds extends AsyncTask<Void, Void, Void> 
implements OnCancelListener{


    protected void onPreExecute() {
    pDialog2.setCancelable(true);
    pDialog2.setOnCancelListener(this);
    }

    @Override
    public void onCancel(DialogInterface dialog) {
    // TODO Auto-generated method stub
    downloadAllFeeds.this.cancel(true);
    Log.d("on click cancel true","true");
    }

    @Override
    protected Void doInBackground(Void... params) {
    if(isCancelled()==true){
    //cancel true stop async
    Log.d("cancel true","true");

    }else{
      //perform your task
     }
}

这对我有用,我知道这是一个非常古老的问题,但它没有答案,所以我想我应该分享我刚才可以实现的内容:)

于 2013-10-01T18:17:52.017 回答