在已经运行的android线程上调用函数?写在侦听蓝牙的同一线程上吗?

时间:2019-01-11 14:23:45

标签: java android multithreading bluetooth

以下问题是关于在用于处理android中的蓝牙套接字的同一线程上进行读写的。

我不明白如何在已经运行的线程上调用write函数。该代码可以正常运行,但是我不明白为什么。

在android dev网站的以下代码中,线程似乎一直在无限循环中进行监听。此外,socket.getInputStream()函数是一个阻塞调用,这意味着它要等到该行执行之前要读取的数据为止。我不明白如何在调用ConnectedThread.write()函数时立即调用该函数。如果线程已经在忙于侦听传入的数据,那么如何write()呢?它应该run()之前完成write()函数吗?而且代码的编写方式似乎run()函数永远不会完成执行,因为它处于无限循环中。

// Code
public class MyBluetoothService {
    private static final String TAG = "MY_APP_DEBUG_TAG";
    private Handler mHandler; // handler that gets info from Bluetooth service

    // Defines several constants used when transmitting messages between the
    // service and the UI.
    private interface MessageConstants {
        public static final int MESSAGE_READ = 0;
        public static final int MESSAGE_WRITE = 1;
        public static final int MESSAGE_TOAST = 2;

        // ... (Add other message types here as needed.)
    }

    private class ConnectedThread extends Thread {
        private final BluetoothSocket mmSocket;
        private final InputStream mmInStream;
        private final OutputStream mmOutStream;
        private byte[] mmBuffer; // mmBuffer store for the stream

        public ConnectedThread(BluetoothSocket socket) {
            mmSocket = socket;
            InputStream tmpIn = null;
            OutputStream tmpOut = null;

            // Get the input and output streams; using temp objects because
            // member streams are final.
            try {
                tmpIn = socket.getInputStream();
            } catch (IOException e) {
                Log.e(TAG, "Error occurred when creating input stream", e);
            }
            try {
                tmpOut = socket.getOutputStream();
            } catch (IOException e) {
                Log.e(TAG, "Error occurred when creating output stream", e);
            }

            mmInStream = tmpIn;
            mmOutStream = tmpOut;
        }

        public void run() {
            mmBuffer = new byte[1024];
            int numBytes; // bytes returned from read()

            // Keep listening to the InputStream until an exception occurs.
            while (true) {
                try {
                    // Read from the InputStream.
                    numBytes = mmInStream.read(mmBuffer);
                    // Send the obtained bytes to the UI activity.
                    Message readMsg = mHandler.obtainMessage(
                            MessageConstants.MESSAGE_READ, numBytes, -1,
                            mmBuffer);
                    readMsg.sendToTarget();
                } catch (IOException e) {
                    Log.d(TAG, "Input stream was disconnected", e);
                    break;
                }
            }
        }

        // Call this from the main activity to send data to the remote device.
        public void write(byte[] bytes) {
            try {
                mmOutStream.write(bytes);

                // Share the sent message with the UI activity.
                Message writtenMsg = mHandler.obtainMessage(
                        MessageConstants.MESSAGE_WRITE, -1, -1, mmBuffer);
                writtenMsg.sendToTarget();
            } catch (IOException e) {
                Log.e(TAG, "Error occurred when sending data", e);

                // Send a failure message back to the activity.
                Message writeErrorMsg =
                        mHandler.obtainMessage(MessageConstants.MESSAGE_TOAST);
                Bundle bundle = new Bundle();
                bundle.putString("toast",
                        "Couldn't send data to the other device");
                writeErrorMsg.setData(bundle);
                mHandler.sendMessage(writeErrorMsg);
            }
        }

        // Call this method from the main activity to shut down the connection.
        public void cancel() {
            try {
                mmSocket.close();
            } catch (IOException e) {
                Log.e(TAG, "Could not close the connect socket", e);
            }
        }
    }
}

代码按预期工作,但我不明白为什么。

2 个答案:

答案 0 :(得分:0)

似乎有些概念有些混乱。我会尝试澄清一下。

  

socket.getInputStream()函数是一个阻塞调用

这只是吸气剂,不会阻塞。 Z是阻止者。

  

那我不明白如何在调用ConnectedThread.write()函数时立即调用该函数。

Y可能被另一个线程调用。在这种情况下,请将Z视为与其他对象一样的通用对象。

编辑

这是一个代码示例,它说明新线程与已经存在的线程一起运行。

socket.getInputStream().read()

答案 1 :(得分:0)

  

我不明白如何在已经运行的线程上调用write函数...

您不是“在线程上调用它”。您正在Thread上调用它。 Thread是程序中的一个对象,其代码可以调用的方法与调用任何其他对象的方法完全相同。 Thread类具有一个非常特殊的实例方法t.start(),该方法创建一个新的操作系统 thread ,但除此之外,它与其他任何Java类一样。

t.start()方法创建一个新的 thread 。新线程调用您的Thread对象的run()方法,然后在run()返回或引发异常之后,新线程死亡。

您没有向我们展示调用write()的其他代码,但这可能就像@nandsito所说的那样:您代码中的其他 thread 正在您的{{ 1}}实例。