使用AsyncTask强制关闭的Android套接字实现

时间:2016-10-21 08:08:25

标签: java android sockets android-asynctask

当我尝试向我的AsyncTask类发送'signal'以停止执行并关闭套接字连接时,我遇到了一个问题。在doInBackground方法中,我设置套接字连接,发送第一个有效负载数据包并等待传入​​数据包:

mRunning = true;

        try {
            byte[] data = null;

            mSocket = mTlsSocketFactory.createSocket(mTlsSocketFactory.getServerAddress(), mTlsSocketFactory.getServerPort());
            LogHelper.printLogMsg("INFO socket created");

            out = new DataOutputStream(mSocket.getOutputStream());
            out.flush();
            inStream = new DataInputStream(mSocket.getInputStream());

            //send authenticate payload
            requestSendPayload(authenticatePayload, params);

            while (mRunning) {
                int type = inStream.readInt();
                type = Integer.reverseBytes(type);
                mResID = type;
                int length = inStream.readInt();
                length = Integer.reverseBytes(length);
                if (length > 0) {
                    data = new byte[length];
                    inStream.readFully(data);
                    publishProgress(data);
                }
                data = null;
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (out != null) out.close();
                if (inStream != null) inStream.close();
                if (mSocket != null) mSocket.close();
            } catch (IOException e) {
                e.fillInStackTrace();
            }
        }

当我收到我想要的数据包时,我应该关闭连接。我在AsyncTask类中有一个公共方法:

public void close() {
   mRunning = false;
}

但问题是'while'块永远不会结束而doInBackground永远不会结束。 有很多帖子有类似的问题,但我试图在我的AsyncTask上调用cancel(true),但没有结果 - doInBackground从未完成。我的问题是如何将'signal'发送到doInBackground方法,以便我的while循环能够完成?

我可以将closeMethod重写为:

new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    if (out != null) out.close();
                    if (inStream != null) inStream.close();
                    if (mSocket != null) mSocket.close();
                } catch (IOException e) {
                    e.fillInStackTrace();
                }
            }
        }).start();

之后,我在尝试阅读时遇到异常:DataInputStream.readInt()然后doInBackground将结束。但我不确定这是否是正确的解决方案。

1 个答案:

答案 0 :(得分:0)

您应该在异步任务方法中实现OnCancelled

@Override
protected void onCancelled() {
   mRunning = false;
}
之后你只需要打电话

mySocketAsyncTaskObject.cancel(false);

另一种选择是删除你的mRunning属性和OnCancelled覆盖,只检查IsCancelled()

while (!IsCancelled()) {
                int type = inStream.readInt();
                type = Integer.reverseBytes(type);
                mResID = type;
                int length = inStream.readInt();
                length = Integer.reverseBytes(length);
                if (length > 0) {
                    data = new byte[length];
                    inStream.readFully(data);
                    publishProgress(data);
                }
                data = null;
            }

作为个人注释,我想补充一点,使用Service类来封装你的Socket功能并使用普通的Thread对象而不是AsyncTask

是一个好习惯。