Android 这是一个糟糕的黑客吗?有更好的方法吗?

Android 这是一个糟糕的黑客吗?有更好的方法吗?,android,bluetooth,bluetooth-lowenergy,Android,Bluetooth,Bluetooth Lowenergy,我有一些代码可以工作,但感觉像是个坏主意。我想知道有没有更好的办法 问题(您可以直接跳过这一步,转到代码) 我有一个蓝牙LE应用程序,偶尔需要尽可能快地将特性写入多个BLE设备(该应用程序是智能灯的控制器)。我目前对BLE通信的设置是使用一个处理所有通信的BluetoothController自定义单例,以及Lamp对象,该对象要求控制器写入Lamp,并将其BluetoothGatt和BluetoothGattCharacteristic传递给控制器 解决方案 handler.post(new

我有一些代码可以工作,但感觉像是个坏主意。我想知道有没有更好的办法

问题(您可以直接跳过这一步,转到代码)

我有一个蓝牙LE应用程序,偶尔需要尽可能快地将特性写入多个BLE设备(该应用程序是智能灯的控制器)。我目前对BLE通信的设置是使用一个处理所有通信的
BluetoothController
自定义单例,以及
Lamp
对象,该对象要求控制器写入Lamp,并将其
BluetoothGatt
BluetoothGattCharacteristic
传递给控制器

解决方案

handler.post(new Runnable() {
                @Override
                public void run() {
                    if (control != null) {
                            synchronized (BluetoothController.this) {
                                Logger.d("BluetoothController", "Waiting......");

                                for(int i = 0; i < 100; i++){
                                    if(isWaiting)
                                        try {
                                            Thread.sleep(10);
                                        } catch (InterruptedException e) {
                                            e.printStackTrace();
                                        }
                                    else
                                        break;
                                }
                                isWaiting = true;

                                Logger.d("BluetoothController", "Done waiting.");
                            }

                        control.setValue(message);
                        mBluetoothGatt.writeCharacteristic(control);
                    }
                }
            });
现在,这段代码可以工作了,但我作为程序员的所有经验告诉我,这段代码会给我带来很多痛苦,当然还有更好的方法

编辑:使用Handler.Callback和Messages创建新代码

我已经修改了代码,使用Thread.wait()和notify()在句柄消息回调中进行等待,但是消息似乎正在队列中备份,最后执行的消息似乎仍然是随机的

@Override
public void run() {
    Looper.prepare();

    handler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            synchronized (BluetoothController.this) {
                if (shouldWait) {
                    isWaiting = true;
                    try {
                        BluetoothController.this.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    isWaiting = false;
                }
                shouldWait = true;
            }
            return true;
        }
    });

    Looper.loop();
}

我同意——轮询很少是个好主意,也许在嵌入式系统中除外。您应该使用Thread.wait(超时)和notify()来中断它,而不是Thread.sleep。我没有足够的代码来提供完整的实现-诀窍是您需要回调井中等待线程的引用…我以前尝试过使用
thread.wait()
,因为这似乎是正确的使用方法,但它不起作用。我只是再次尝试实现它,它的效果和我的解决方案一样好。我想有时候就是这样。将此作为答案提交,这样您就可以获得甜蜜、多汁的声誉。嗯,这个解决方案遇到了一个问题…在尝试发送一堆之后发送的最后一个请求几乎是随机的,不一定是我尝试发送的最后一个请求。很难说没有看到完整的结构,但是我发现您在
Runnable
之外同时使用了控件和消息,因此非线程安全操作可能会给您带来问题。您是否可以进行重构,以便使用一个队列,如果队列为空,则使用单个Runnable wait()s,并在向队列添加内容时通知()。然后,它可以从队列中提取消息并对其进行处理,最大限度地减少线程外变量的使用(您需要在队列数据结构上进行同步)签出编辑;我想我理解你的意思,但我不认为我在编辑中加入的内容正是你所说的。我是否有办法控制消息何时/如何从队列中弹出?
@Override
public void run() {
    Looper.prepare();

    handler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            synchronized (BluetoothController.this) {
                if (shouldWait) {
                    isWaiting = true;
                    try {
                        BluetoothController.this.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    isWaiting = false;
                }
                shouldWait = true;
            }
            return true;
        }
    });

    Looper.loop();
}