2017-09-25 111 views
0

我是Rx的新手,仍在努力弄清楚如何正確處理觀察對象。我想知道是否有更好的方法來編寫多個特性,而不是使用RxAndroidBle一次完成一個特性?目前,我一次只做一個,代碼如下。用RxAndroidBle編寫多個特徵的正確方法是什麼?

Observable<RxBleConnection> mConnectionObservable; 

private void saveChanges(String serialNumber, Date date, MachineTypeEnum machineType, MachineConfig machineConfig) { 
    mWriteSubscription = mConnectionObservable 
      .flatMap(rxBleConnection -> Observable.merge(
        getWrites(rxBleConnection, serialNumber, machineType, machineConfig, date) 
      )) 
      .observeOn(AndroidSchedulers.mainThread()) 
      .subscribe(bytes -> { 
       Toast.makeText(getContext(), "Saved Changes", Toast.LENGTH_SHORT).show(); 
       ((MainActivity)getActivity()).back(); 
      }, BleUtil::logError); 
} 

private Iterable<? extends Observable<? extends byte[]>> getWrites(RxBleConnection rxBleConnection, 
                    String serialNumber, 
                    MachineTypeEnum machineType, 
                    MachineConfig machineConfig, 
                    Date date) { 
    List<Observable<byte[]>> observables = new ArrayList<>(); 


    observables.add(rxBleConnection.writeCharacteristic(
      Constants.Bluetooth.Services.DrainCleaner.Characteristics.UUID_WRITE_SERIAL_NUMBER, 
      Utf8Util.nullPad(serialNumber, 16).getBytes()).doOnError(throwable -> Log.e("Write", "serial failed", throwable))); 

    observables.add(rxBleConnection.writeCharacteristic(
      Constants.Bluetooth.Services.DrainCleaner.Characteristics.UUID_MACHINE_TYPE, 
      new byte[]{(byte) machineType.val()}).doOnError(throwable -> Log.e("Write", "machine type failed", throwable))); 

    observables.add(rxBleConnection.writeCharacteristic(
      Constants.Bluetooth.Services.DrainCleaner.Characteristics.UUID_CHARACTERISTIC, 
      MachineConfigBitLogic.toBytes(machineConfig)).doOnError(throwable -> Log.e("Write", "machine config failed", throwable))); 

    observables.add(rxBleConnection.writeCharacteristic(
      Constants.Bluetooth.Services.CurrentTime.Characteristics.UUID_CURRENT_TIME, 
      TimeBitLogic.bytesFor(date)).doOnError(throwable -> Log.e("Write", "date failed", throwable))); 

    return observables; 
} 

因此,我改變了我的舊代碼,現在使用合併,但只有一個特性現在似乎更新。

回答

2

我會用merge操作:

mConnectionObservable 
     .flatMap(rxBleConnection -> 
     Observable.merge(
     rxBleConnection.writeCharacteristic(
      Constants.Bluetooth.Services.DeviceInformation.Characteristics.UUID_SERIAL_NUMBER, 
      Utf8Util.nullPad(serialNumber, 16).getBytes() 
     ), 
     rxBleConnection.writeCharacteristic(
      Constants.Bluetooth.Services.DrainCleaner.Characteristics.UUID_MACHINE_TYPE, 
      new byte[]{(byte) machineType.val()} 
     )) 
     .subscribe(bytes -> {/* do something*/}, BleUtil::logError); 

你也可以通過觀測到運營商的列表:

而是通過多個觀測量(最多9個)爲合併的,你 也可以傳遞一個List(或其他Iterable)的Observable,一個 Observable數組,或者甚至可以傳出Observable的Observable, 並且合併會將它們的輸出合併到輸出中單 可觀察

+0

雖然我遇到了使用合併的問題。這似乎只有一個特點被寫入這種方法。我將使用當前的代碼添加編輯。 –

+0

看起來像其中一個observables拋出一個錯誤。 –

1

RxAndroidBle庫序列化引擎蓋下的任何BLE請求在Android上進行BLE實現主要是同步的(雖然Android的香草API表明它不是)。

的寫入Mergeing是一個很好的方法,雖然你需要知道的合併運營商做什麼:

* You can combine the items emitted by multiple Observables so that they appear as a single Observable, by 
* using the {@code merge} method. 

所以我改變了我的舊代碼,以高於自己現在使用合併,但只其中一個特徵現在似乎更新了。

其原因行爲可能是你如何消費流:

 .subscribe(bytes -> { 
      Toast.makeText(getContext(), "Saved Changes", Toast.LENGTH_SHORT).show(); 
      ((MainActivity)getActivity()).back(); 
     }, BleUtil::logError); 

每當bytes發射您呼叫Activity.back().merge()對於執行的每個寫入命令,操作員都會發出bytes。如果您退訂Subscription.onPause(),那麼在第一次寫入完成後它將立即取消訂閱。 你可以讓你的流程等待,直到所有的寫入都像這樣完成:

private void saveChanges(String serialNumber, Date date, MachineTypeEnum machineType, MachineConfig machineConfig) { 
    mWriteSubscription = mConnectionObservable 
     .flatMap(rxBleConnection -> 
      Observable.merge(
       getWrites(rxBleConnection, serialNumber, machineType, machineConfig, date) 
      ) 
      .toCompletable() // we are only interested in the merged writes completion 
      .andThen(Observable.just(new byte[0])) // once the merged writes complete we send a single value that will be reacted upon (ignored) in .subscribe() 
     ) 
     .observeOn(AndroidSchedulers.mainThread()) 
     .subscribe(ignored -> { 
      Toast.makeText(getContext(), "Saved Changes", Toast.LENGTH_SHORT).show(); 
      ((MainActivity)getActivity()).back(); 
     }, BleUtil::logError); 
} 
+0

感謝您的幫助!它現在按預期工作! –

相關問題