Jouke Waleson
Jouke Waleson

Reputation: 517

Android stop download

In my application I download and parse a html page. However, I want to be able to stop the download in its tracks (i.e. when the user hits cancel).

This is the code I use now, which is being called from doInBackground from ASyncTask.

How do I cancel this request from outside of the ASyncTask?

I currently use 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;
   }

Upvotes: 0

Views: 1272

Answers (2)

Jouke Waleson
Jouke Waleson

Reputation: 517

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.

Upvotes: 1

ns476
ns476

Reputation: 385

Can't you use AsyncTask.cancel()? You should be able to then use the onCancelled callback to return to the main activity..

Upvotes: 1

Related Questions