顺序等待语句

Wait statement that are sequential

我遇到了一个问题,导致需要按顺序等待从一件事进入另一件事。我目前通过设置 3 个具有不同延迟的可运行对象来实现这一点,以允许顺序数据流出现在我的蓝牙连接上。然而,虽然这确实有效,但我觉得必须有更好/更清洁的实现。我现在的代码如下。

我的代码是这样工作的:

请你给我一些建议,如何更好地一个接一个地执行我的写入功能。

Handler h =new Handler() ;
h.postDelayed(new Runnable() {
    public void run() {
        Log.d(TAG, "Write 1");
        mBluetoothLeService.writeCharacteristic(10);
    }
}, 1000);

Handler h1 =new Handler() ;
final int Command_to_run = value;
h1.postDelayed(new Runnable() {
    public void run() {
        Log.d(TAG, "Write 2");
        mBluetoothLeService.writeCharacteristic(Command_to_run);
    }
}, 2000);

Handler h2 =new Handler() ;
h2.postDelayed(new Runnable() {
    public void run() {
        Log.d(TAG, "Write 3");
        mBluetoothLeService.writeCharacteristic(20);
    }
}, 3000);

编写代码

 public void writeCharacteristic(int Data) {
        if (mBluetoothAdapter == null || mBluetoothGatt == null) {
            Log.w(TAG, "BluetoothAdapter not initialized");
            return;
        }

        byte[] value = intToByteArray(Data);

        BluetoothGattService mCustomService = 
        mBluetoothGatt.getService(UUID.fromString("f3641400-00b0-4240-ba50- 
        05ca45bf8abc"));
        if(mCustomService == null){
            Log.w(TAG, "Custom BLE Service not found");
            return;
        }
        /*get the read characteristic from the service*/
        BluetoothGattCharacteristic characteristic = 
        mCustomService.getCharacteristic(UUID.fromString("f3641401-00b0-4240- 
        ba50-05ca45bf8abc"));
        characteristic.setValue(value);
        mBluetoothGatt.writeCharacteristic(characteristic);
    }

如果你想按顺序执行的工作可以异步完成,你可以考虑 Android Jetpack 中包含的新 WorkManager。使用 WorkManager,您可以非常巧妙地组织所有工作,根据文档,您可以按如下方式进行:

WorkManager.getInstance(myContext)
   // Candidates to run in parallel
   .beginWith(listOf(filter1, filter2, filter3))
   // Dependent work (only runs after all previous work in chain)
   .then(compress)
   .then(upload)
   // Don't forget to enqueue()
   .enqueue()

图书馆会为您妥善处理执行顺序。您可以在此处找到有关此事的更多信息:https://developer.android.com/topic/libraries/architecture/workmanager/how-to/chain-work

我认为 mBluetoothLeService.writeCharacteristic(10); 像这样的调用已经阻塞了线程,因此在不需要处理程序的情况下按顺序使用它们可能是您的解决方案。我不认为那个函数是异步的,所以如果 return 是真的,你可以写下一个。它们是布尔函数,因此如果 return 为真,您可以切换到下一个。

我已经检查了源代码,如果它在其中抛出异常,那么它 return 是错误的。否则,它 returns 是否成功。

旁注:这种行为在不同的 API 版本上可能会有所不同,我研究过的源代码是针对 API 29 的。不过,我相信行为是相同的,除了您可能需要将 mBluetoothLeService.writeCharacteristic(10); 调用包装到 try-catch 块。

我必须编辑这个,因为答案是错误的,布尔值 return 不足以判断操作是否成功。该操作确实是异步的,但是您可以使用一个回调 (this callback) 查看写入操作是否成功,然后继续进行下一个操作。

查看 了解更多信息,如果可能,请去掉这一项的勾号。

Android 的 BLE API 是完全异步的,没有阻塞方法。如果操作成功启动,这些方法将 return 为真,否则为假。特别是,如果已经有操作正在进行,将 return 编辑 false。

当你调用requestMtuwriteCharacteristicreadCharacteristic等时,相应的回调onMtuChangedonCharacteristicWriteonCharacteristicRead会操作完成时调用。请注意,这通常意味着到远程设备的往返,这可能需要不同的时间来完成,具体取决于环境的嘈杂程度和您拥有的连接参数,因此休眠或延迟一些固定的时间永远不是一个好主意时间并假设操作已完成。

为了使代码结构更好一点并避免 "callback hell",您可以例如实现一个(线程安全的)GATT 队列,稍后您的应用程序将使用它。这样你就可以把你想要的东西推到队列中,让你的 GATT 队列库处理脏东西。或者您可以使用一些已经执行此操作的 Android BLE 库。

请参阅 https://medium.com/@martijn.van.welie/making-android-ble-work-part-3-117d3a8aee23 以获得更详尽的讨论。