【问题标题】:Wait statement that are sequential顺序的等待语句
【发布时间】:2020-03-05 14:30:17
【问题描述】:

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

我的代码是这样工作的:

  • 写命令1
  • 等到命令写入
  • 写命令2
  • 等到命令写入
  • 写命令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);
    }

【问题讨论】:

  • 我认为像这样的mBluetoothLeService.writeCharacteristic(10); 调用已经阻塞了线程,因此在不需要处理程序的情况下按顺序使用它们可以成为您的解决方案。我不认为那个函数是异步的,所以如果它返回true,你可以写下一个。它们是boolean 函数,所以如果它返回true,你可以切换到下一个。
  • 不幸的是,我不这么认为。我已经修改了我的主要问题以包括函数本身。其中,返回无效。话虽如此,我认为我可以更改代码以包含来自 mBluetoothGatt.writeCharacteristic 的嵌入式布尔返回。但是,一旦完成,这会返回 true 吗?
  • 我相信是的。我检查了源代码,如果它在其中抛出异常,它会返回 false。否则,无论成功与否,都会返回。
  • 邪恶的我会考虑改变它。您能否将其发布为答案。
  • @FurkanYurdakul 我已经实现了一个布尔检查写入是否完成,这解决了我的问题并加快了传输速度。请您将其发布为答案。

标签: java android bluetooth-lowenergy delay wait


【解决方案1】:

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

我检查了源代码,如果它在其中抛出异常,它会返回 false。否则,无论成功与否,都会返回。

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

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

请查看this answer 了解更多信息,如果可能的话,请去掉这个勾号。

【讨论】:

  • 不,这整个答案是完全错误的。 Android 的 BLE API 是完全异步的,没有阻塞方法。这就是 onCharacteristicWrite 回调等的用途。当得到对应的回调后,就可以执行下一个操作了。
【解决方案2】:

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

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

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

请参阅https://medium.com/@martijn.van.welie/making-android-ble-work-part-3-117d3a8aee23 进行更深入的讨论。

【讨论】:

  • 干杯这是一个很好的答案。我确实有一个半相关的问题要问你。我目前正在使用一个应用程序来建立连接并查看服务和特征并将它们添加到列表中。我想要一个按钮,单击该按钮会为该特征值设置通知。目前我必须在列表中单击它。我确实有 UUID
  • 抱歉,您的具体问题是什么?如何构建一个带有按钮的 UI,或者如何为某个特征或其他东西启用通知?
  • 我可以在列表视图之外启用通知。我希望能够通过按下按钮而不是单击列表视图中的项目来执行此操作。我在这里有另一个问题。基本上我希望能够从我填充的列表中访问我的特征,但是,从一个按钮。 stackoverflow.com/questions/60992229/…
【解决方案3】:

如果您想按顺序执行的工作可以异步完成,您可以考虑 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

【讨论】:

    猜你喜欢
    • 2020-09-11
    • 2016-08-16
    • 2020-04-25
    • 2020-07-23
    • 1970-01-01
    • 1970-01-01
    • 2017-10-26
    • 2012-07-24
    • 1970-01-01
    相关资源
    最近更新 更多