强制停止阻塞读取AsyncTask

时间:2015-09-09 10:48:31

标签: java android sockets android-asynctask

我的应用程序中有一个AsyncTask:

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;
        }
        ...
    }

我想在关闭应用程序时停止AsyncTask task :(按回putton)。 我在Android - Cancel AsyncTask Forcefully尝试了答案来检查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);
    }

但是,当调用myInputstream.read(readbyte)时,应用程序似乎会在task.cancle(true)处阻止。 Android将弹出一个“应用程序停止响应..”弹出窗口给我。 我如何强制停止阻止读取?

1 个答案:

答案 0 :(得分:1)

myInputstream.read(readbyte) 实现阻止I / O.预计您的应用程序将阻止

read

直到-1操作返回Socket,这意味着没有更多数据要从流中读取(因为它已关闭或连接已终止)或抛出异常。

解除线程中等待数据的线程的唯一方法是关闭它。在您的情况下,您需要能够关闭在

中创建的mySocket = new Socket();
mySocket.close();

线。

SocketException

应该打断你的阅读。但请注意Socket.close()实际

  

关闭此套接字。

     

此套接字上的I / O操作中当前阻塞的任何线程都将抛出SocketException。

因此,您的任务步骤将被取消阻止,但您必须在任务中正确处理task.cancel(true); 以终止所有操作(可能这是您缺少的)。

FYI致电

cancelled

没有多大意义,因为这只会在任务上设置CHAR(2) CHARACTER SET ascii标志。您的代码负责检查标志,并且阻止I / O您无法执行此操作。

或者,您应该考虑使用非阻塞I / O.