3

I am creating simple class which sends requests using HttpURLConnection to server and receive responses. I want to add interrupt() method which interrupt current request (imagine request is running in AsyncTask and interrupt() is called from main thread). There are 2 processes which takes a lot of time and I don't know how to interrupt them:

  • writing to output stream
  • reading from input stream

So let's say that I want to for example interrupt reading from input stream which I read like this:

downloadThread = new Thread(new Runnable() {
    @Override
    public void run() {
        try {
            buffer = readFully(connection.getInputStream());
        } catch( Exception e ) {
            e.printStackTrace();
        }
    }
});
downloadThread.start();

And readFully() method is:

public byte[] readFully(InputStream input) throws IOException {
    byte[] buffer = new byte[8192];
    int bytesRead;
    ByteArrayOutputStream output = new ByteArrayOutputStream();
    while ((bytesRead = input.read(buffer)) != -1) {
        output.write(buffer, 0, bytesRead);
    }
    return output.toByteArray();
}

How can I stop reading from input stream (in other words, downloading) ? stop() method of Thread is deprecated and cannot be used. There are written everywhere that I should regularly check if thread should be stopped and stop it manually. But how can I do that when whole time takes this line (If I understand well):

connection.getInputStream()

I think this is the same kind of question but it is unanswered (see comments of solution): How to stop HttpURLConnection connect on Android Please, don't refer me to some REST library. I would really like to know how to handle this issue. Thanks ;).

Community
  • 1
  • 1
1daemon1
  • 1,001
  • 3
  • 11
  • 29

2 Answers2

4

connection.getInputStream() will return as soon as a connection is established with the server and the client is ready to start streaming the response.

So it depends on the connection: if you're e.g. downloading a large file, then most (nearly all) of the time should be spent inside the readFully() method while it is streamed, while if the response is extremely short of empty then readFully() will do very little.

In the first case, the easiest way to "interrupt" is to set a boolean flag and check it inside the loop.

while ((bytesRead = input.read(buffer)) != -1)
{
    if (cancelled)
        return null;

    output.write(buffer, 0, bytesRead);
}

This "boolean flag" can be the isCancelled() method if you're implementing this inside an AsyncTask's doInBackground() (recommended).

In the second case, there's not much you can do, short of killing the thread outright (not recommended at all).

matiash
  • 54,791
  • 16
  • 125
  • 154
1

I think it would be better to implement it using Android AsyncTask class.

http://developer.android.com/reference/android/os/AsyncTask.html#cancel(boolean)

There is a method cancel() there and also isCancelled() which you could use to check if the task was cancelled and exit the InputStream reading loop.

Aleksander Lech
  • 1,105
  • 12
  • 16