0

在我的应用程序中,我下载并解析了一个 html 页面。但是,我希望能够在其轨道上停止下载(即当用户点击取消时)。

这是我现在使用的代码,它是从 ASyncTask 的 doInBackground 调用的。

如何从 ASyncTask 外部取消此请求?

我目前使用htmlcleaner

   HtmlCleaner cleaner = new HtmlCleaner();
   CleanerProperties props = cleaner.getProperties();
   props.setAllowHtmlInsideAttributes(true);
   props.setAllowMultiWordAttributes(true);
   props.setRecognizeUnicodeChars(true);
   props.setOmitComments(true);
   try {
        URL url = new URL(urlstring);
        URLConnection conn = url.openConnection();
        TagNode node = cleaner.clean(new InputStreamReader(conn.getInputStream()));
        return node;
   } catch (Exception e) {
       failed = true;
       return;
   }
4

2 回答 2

1

Ok, I believe I've solved this.

In my Activity class I have a variable (boolean) failed. Also, I have a private Downloader class within the activity which extends ASyncTask. This way, the Downloader class has access to the failed boolean. When the Activity launches, it starts the Downloader task and a progress dialog pops up. When the task finishes, it closes the dialog and then goes on processing the downloaded content.

However, when the user cancels the progress dialog, failed is set to true, and the user is sent back to the previous activity by a call to finished. In the meantime, Downloader is still busy downloading. Because the results are now unneccessary, we want it to stop using resources asap. In order to accomplish this, I have broken up the doInBackground method in as much steps as possible. After each step I check if failed is still false, when it is set to true, it simply doesn't go to the next step. See it in action below. Furthemore, the BufferedReader reader is public, and in the onCancelled method I execute reader.close(). This will throw all sorts of exceptions, but these are properly caught.

 public void DoInBackground(.........) {
    try {
        URL url = new URL(uri);
        URLConnection conn = url.openConnection();
        if (!failed) {
            isr = new InputStreamReader(conn.getInputStream());
            if (!failed) {
                reader = new BufferedReader(isr);
                publishProgress(1);
                if (!failed) {
                    TagNode node = cleaner.clean(reader);
                    publishProgress(2);
                    return node;
                }
            }
        }
     } catch (Exception e) {
          failed = true;
          Log.v("error",""+e);
     } 
 }

@Override
protected void onCancelled() {
    failed = true;
    if (reader != null)
        try {
            reader.close();
        } catch (IOException e) {
            failed = true;
        }
    if (isr != null)
        try {
            isr.close();
        } catch (IOException e) {
        }
}

I know that I could have broken up the downloading process in even tinier bits, but I am downloading very small files, so it's not that important.

于 2011-03-24T18:17:52.733 回答
1

你不能用AsyncTask.cancel()吗?然后您应该能够使用onCancelled回调返回到主要活动..

于 2011-02-06T16:31:13.533 回答