【问题标题】:Resume flowable converted to live data after screen rotation屏幕旋转后恢复流转换为实时数据
【发布时间】:2017-11-19 22:41:25
【问题描述】:

假设我有这样的活动:

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 在暂停时取消订阅并在恢复时重新订阅,因此倒计时重新开始。

我猜我应该在我的 RxJava 部分代码中更改一些内容以使其正常工作。关于改变什么的任何想法?

【问题讨论】:

    标签: java android rx-java android-architecture-components android-livedata


    【解决方案1】:

    感谢 Android United Slack channel 的 Svyatoslav Lebeckiy,他向我指出了 BehaviorSubjectBehaviorProcessor,并提出了解决此问题的想法。

    我将视图模型更改为:

    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 中开始倒计时一次,在startCountdown 中创建的BehaviorProcessor 负责将最后一个和随后发出的值传递给它的订阅者(在这种情况下为LiveData)。

    由于LiveDataReactiveStreams 需要Flowable,所以在这里使用BehaviorProcessor 代替BehaviorSubject 很方便。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-31
      • 1970-01-01
      • 1970-01-01
      • 2011-07-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多