假设我有这样的活动:
public class TestActivity extends AppCompatActivity { @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); final TextView countdown = new TextView(this); setContentView(countdown); ViewModelProviders.of(this) .get(TestViewModel.class) .getCountdown() .observe(this, countdown::setText); } }
视图模型为:
class TestViewModel extends ViewModel { private final LiveData<String> countdown = LiveDataReactiveStreams.fromPublisher( Flowable.concat( Flowable.just("Falcon Heavy rocket will launch in..."), Flowable.intervalRange(0, 10, 3, 1, TimeUnit.SECONDS) .map(x -> String.valueOf(10 - x)), Flowable.timer(1, TimeUnit.SECONDS) .map(ignored -> "Lift off!") ) ); LiveData<String> getCountdown() { return countdown; } }
我想正确处理旋转,因此,如果用户在倒数计时为5时旋转设备,我希望旋转后的下一个值为5(如果第二个已经过去,则为4),只要在倒数应该实际出现的任何地方取。
如果火箭已经升空,我希望它在旋转后保持这种状态,我不希望倒计时再次开始。
此刻,LiveDataReactiveStreams暂停时取消订阅,恢复时进行新订阅,因此倒计时重新开始。
LiveDataReactiveStreams
我猜想我应该在代码的RxJava部分中进行一些更改才能使其正常工作。有什么想法要改变吗?
由于斯维亚托斯Lebeckiy了在Android的美国时差通道谁指出,BehaviorSubject和BehaviorProcessor我,提出了关于如何解决此问题的想法。
BehaviorSubject
BehaviorProcessor
我将视图模型更改为:
class TestViewModel extends ViewModel { private LiveData<String> countdown; LiveData<String> getCountdown() { if (countdown == null) { countdown = LiveDataReactiveStreams.fromPublisher(startCountdown()); } return countdown; } private static Flowable<String> startCountdown() { final BehaviorProcessor<String> processor = BehaviorProcessor.create(); Flowable.concat( Flowable.just("Falcon Heavy rocket will launch in..."), Flowable.intervalRange(0, 10, 3, 1, TimeUnit.SECONDS) .map(x -> String.valueOf(10 - x)), Flowable.timer(1, TimeUnit.SECONDS) .map(ignored -> "Lift off!") ).subscribe(processor); return processor; } }
这样,我只能倒数一次开始计时,getCountdown并且BehaviorProcessor创建时startCountdown负责将最后一个随后发出的值传递给其订户(LiveData在这种情况下)。
getCountdown
startCountdown
LiveData
由于LiveDataReactiveStreams需要a Flowable,因此使用a BehaviorProcessor代替BehaviorSubject此处很方便。
Flowable