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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With