等待接收数据而不阻止ui线程蓝牙android

时间:2019-07-05 13:39:37

标签: java android bluetooth android-runonuithread

我是Android编程的新手,我正在编写一个使用蓝牙的回合制游戏的简单应用程序。 我的应用程序由Main Activity组成,负责启动蓝牙连接和交换一些配置消息,以及一个SecondActivity,后者通过游戏地图实现自定义视图。 我什至可以在自定义视图中正确配对设备并在两者之间交换信息,问题是在自定义视图中,我将等待接收信息而不会阻塞ui线程,此刻我正在等待以这种方式接收数据

自定义视图

state = bluetoothService.getState();
while(state != NOT_EMPTY){
    try {
        Thread.sleep(500);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    state = bluetoothService.getState();
}
info = bluetoothService.getMessage();

这显然会导致黑屏和无响应,还有另一种等待接收数据的方法吗?

通过具有线程的BluetoothService类管理连接,负责读取数据的线程执行此操作

private class ConnectedThread extends Thread {
        private final BluetoothSocket mSocket;
        private final InputStream mInStream;
        private final OutputStream mOutStream;

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

            try {
                tmpIn = mSocket.getInputStream();
                tmpOut = mSocket.getOutputStream();
            } catch (IOException e) {
                e.printStackTrace();
            }

            mInStream = tmpIn;
            mOutStream = tmpOut;
        }

        public void run(){
            byte[] buffer = new byte[1024]; 

            int bytes; // bytes returned from read()

            // Keep listening to the InputStream until an exception occurs
            while (true) {
                // Read from the InputStream
                try {
                    bytes = mInStream.read(buffer);
                    if(bytes != 0) {
                        String incomingMessage = new String(buffer, 0, bytes);
                        message = incomingMessage;
                        mState = NOT_EMPTY;
                    }
                } catch (IOException e) {
                    break;
                }
            }
        }
}

//getMessage method just returns message if not null

1 个答案:

答案 0 :(得分:2)

主要思想不是退出活动,而是从后台线程调用活动的方法。

因此,在构造阅读器线程时,请传递对活动的引用并创建处理程序:

    private SecondActivity mActivity;
    private Handler mActivityHandler;

    public ConnectedThread(BluetoothSocket socket, SecondActivity activity) {
        mActivity = activity;
        mActivityHandler = new Handler(activity.getMainLooper());

        ...
    }

收到消息后,调用活动的方法。该调用必须在主线程上完成,因此请使用处理程序:

final String message = incomingMessage;
Runnable runnable = new Runnable() {
    @Override 
    public void run() {
        mActivity.onMessageReceived(message);
    } 
};
mActivityHandler.post(myRunnable);

在活动中,对消息执行以下操作:

public void onMessageReceived(String message) {
    // handle the message...
}