我有一个相当复杂的Rx代码链,用于执行许多操作。基本上在启动时,Observable开始发出一个项目列表。对于每个项目,建立连接(这些项目是BLE设备)并写入特征。
此特性每10秒重写一次,直到发生错误(例如拔出电池)。之后,原始列表中的下一个项目将连接到,依此类推。
以下是大部分行动发生的地方:
public Observable<String> connectForPolice(String name, RemovalListener listener) {
StringBuilder builder = new StringBuilder(mAddress);
builder.setCharAt(mAddress.length() - 1, '4');
RxBleDevice device = mRxBleClient.getBleDevice(builder.toString());
return device.establishConnection(mContext, false)
.timeout(12, TimeUnit.SECONDS)
.doOnError(throwable -> {
Log.d(TAG, "Error thrown after timeout.");
throwable.printStackTrace();
})
.flatMap(new Func1<RxBleConnection, Observable<byte[]>>() {
@Override
public Observable<byte[]> call(RxBleConnection rxBleConnection) {
byte[] value = new byte[1];
value[0] = (byte) (3 & 0xFF);
return Observable // ... we return an observable ...
.defer(() -> {
return rxBleConnection.writeCharacteristic(Constants.BUZZER_SELECT, value);
})
.repeatWhen(observable -> {
return observable.delay(10, TimeUnit.SECONDS);
});
}
})
.observeOn(AndroidSchedulers.mainThread())
.onErrorResumeNext(throwable -> {
throwable.printStackTrace();
listener.onFinished(name);
return Observable.empty();
});
}
这里有一些问题。如您所见,传统的侦听器被传递到此方法中,并且此侦听器在onErrorResumeNext
中调用。此侦听器用于从Activity中的RecyclerView中删除该项,但这并不重要。问题是,以这种方式使用侦听器是一种Rx的反模式。以下是相关代码的其余部分,包括调用上述示例的代码:
@Override
public void onFinished(String deviceName) {
mAdapter.removeItem(deviceName);
}
private void startConnecting() {
mIsBeepingAll = true;
mConnectingSubscription = Observable.from(mAdapter.getItems())
.flatMap((Func1<Device, Observable<?>>) device -> {
Log.d(TAG, "connecting for policing");
return device.connectForPolice(device.getName(), PoliceActivity.this);
}, 1)
.doOnError(throwable -> throwable.printStackTrace())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<Object>() {
@Override
public void onCompleted() {
Log.d(TAG, "onCompleted...");
}
@Override
public void onError(Throwable e) {
e.printStackTrace();
Log.d(TAG, "onError...");
}
@Override
public void onNext(Object o) {
Log.d(TAG, "onNext... ");
}
});
}
包含了侦听器的实现。问题是,如何使用Rx执行与侦听器相同的操作?
答案 0 :(得分:1)
最简单的是改变这个:
.onErrorResumeNext(throwable -> {
throwable.printStackTrace();
listener.onFinished(name);
return Observable.empty();
});
进入这个:
.onErrorResumeNext(throwable -> {
throwable.printStackTrace();
return Observable.just(name);
});
调用者会使用:
private void startConnecting() {
mIsBeepingAll = true;
mConnectingSubscription = Observable.from(mAdapter.getItems())
.flatMap((Func1<Device, Observable<?>>) device -> {
Log.d(TAG, "connecting for policing");
return device.connectForPolice(device.getName(), PoliceActivity.this);
}, 1)
.doOnError(throwable -> throwable.printStackTrace())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<Object>() {
@Override
public void onCompleted() {
Log.d(TAG, "onCompleted...");
}
@Override
public void onError(Throwable e) {
e.printStackTrace();
Log.d(TAG, "onError...");
}
@Override
public void onNext(String deviceName) {
Log.d(TAG, "onNext... ");
mAdapter.removeItem(deviceName);
}
});
}