9

I have an AsyncTask in my application:

public class myActivity extends Activity {
    private static Socket mySocket;
    private static InputStream myInputstream;
    private AsyncTask task;
    private boolean connected = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        ...            
        task = new UpdateTask().execute();
        ...
    }

    private class myTask extends AsyncTask<Void, String, String> {
        @Override
        protected String doInBackground(Void... v) {
            if(!connected) {
                try {
                    mySocket = new Socket();
                    mySocket.connect(new InetSocketAddress(MYIP, MYPORT));
                    myInputstream = mySocket.getInputStream();
                    connected = true;
                } catch(IOException e) { ... }
            }

            while(connected && !isCancelled()) {
                byte[] readbyte = new byte[1024];
                try {
                    myInputstream.read(readbyte);
                } catch (IOException e) { ... }
                ...
            }
            return null;
        }
        ...
    }

And I want to stop AsyncTask task when I close my application: (press back putton). I tried the answer here Android - Cancel AsyncTask Forcefully to check isCancelled()

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if(keyCode == KeyEvent.KEYCODE_BACK) {
            task.cancel(true);
            mySocket.close();
            finish();
        }
        return super.onKeyDown(keyCode, event);
    }

But it seems that application will block at myInputstream.read(readbyte) when task.cancle(true) is called. Android will throw an "app is stop responding.." pop-up to me. How can I force stop the blocking read?

Community
  • 1
  • 1
Dia
  • 851
  • 1
  • 15
  • 35
  • Do you catch any exceptions in doInBackground? There should be an InterruptedException. – Fildor Sep 09 '15 at 10:59
  • @Fildor it should be a `java.io.InterruptedIOException`, but only if the stream supports interruption. – SpaceTrucker Sep 09 '15 at 11:03
  • You say " it seems that application will block at `myInputstream.read(readbyte)`". How sure are you that that is actually the case? – SpaceTrucker Sep 09 '15 at 11:53
  • Because I use many `Log.d()` to print between the lines, it stopped at `read(readbyte)` – Dia Sep 09 '15 at 12:02
  • `mySocket.connect(new InetSocketAddress(MYIP, MYPORT));`. You cannot do that in onCreate. The whole idea of using an AsyncTask is that you put such 'internet code' in doInBackground of an AsyncTask. – greenapps Sep 09 '15 at 12:09
  • Get it, I modify the part into `doInBackground ` – Dia Sep 09 '15 at 12:54
  • This is more like a java-related question, check this SO question: http://stackoverflow.com/questions/4182491/how-to-stop-a-thread-waiting-in-a-blocking-read-operation-in-java – FlyingPumba Feb 29 '16 at 13:58

1 Answers1

1

java.io.InputStream implements blocking I/O. It is expected that your application will block on

myInputstream.read(readbyte)

until the read operation will return -1 which means that there no more data to read from stream (as it was closed or connection was terminated) or throw the exception.

The only way to unblock the thread waiting for data on stream is to close it. In your case you need to be able to close the Socket created in

mySocket = new Socket();

line.

mySocket.close();

should interrupt your reading. But stay aware that Socket.close() actually

Closes this socket.

Any thread currently blocked in an I/O operation upon this socket will throw a SocketException.

So you task tread will get unblocked but you have to handle the SocketException correctly in your task to terminate all operations (maybe this is what you are missing).

FYI calling the

task.cancel(true);

doesn't make much sense as this only sets the cancelled flag on task. It is responsibility of your code to check for the flag and with blocking I/O you have no possibility to do it.

Alternatively you should consider using non-blocking I/O.

Aleh Maksimovich
  • 2,622
  • 8
  • 19