我正在为 Android 应用程序开发启动屏幕,它有一些要求:
- 当显示初始屏幕时,我需要从 存储库。一旦获取该值,它将用于启动 3 并行地对存储库进行不同的调用。
- 启动画面 必须显示至少 3 秒或获取所有内容所需的时间 来自存储库的值(如果获取时间超过 3 秒)。
- 如果在获取第一个值时发生错误 然后可观察链可以终止(一旦 3 几秒钟过去了)
- 如果在获取下一个数据时发生任何错误 可观察链不应终止的三个值,即所有 即使其中一个或多个失败,三个也应该运行。
这是我目前拥有的:
Observable<Long> timerObservable = Observable.timer(3, TimeUnit.SECONDS);
cachedObservable = mLoginRepository
.fetchLoginPreference()
.onErrorReturn(new Func1<Throwable, LoginPreference>() {
@Override
public LoginPreference call(Throwable throwable) {
return null;
}
})
.flatMap(new Func1<LoginPreference, Observable<CompositeLPLCPalette>>() {
@Override
public Observable<CompositeLPLCPalette> call(final LoginPreference loginPreference) {
if (loginPreference == null
|| loginPreference.getActivationCode() == null
|| loginPreference.getActivationCode().isEmpty()) {
Timber.d("login preference was null");
return Observable.just(null);
}
final String activationCode = loginPreference.getActivationCode();
Observable<LoginCapability> loginCapabilityObservable = mLoginRepository
.fetchLoginCapability(activationCode, true)
.onErrorReturn(new Func1<Throwable, LoginCapability>() {
@Override
public LoginCapability call(Throwable throwable) {
return null;
}
});
Observable<OrgContactInfo> orgContactInfoObservable = mLoginRepository
.fetchOrgContactInfo(activationCode, true)
.onErrorReturn(new Func1<Throwable, OrgContactInfo>() {
@Override
public OrgContactInfo call(Throwable throwable) {
Timber.d("Error fetching org contact info");
return null;
}
});
Observable<Palette> paletteObservable = mLoginRepository
.fetchThemeInformation(activationCode, true)
.onErrorReturn(new Func1<Throwable, Palette>() {
@Override
public Palette call(Throwable throwable) {
Timber.d("Error fetching Palette");
return null;
}
});
return Observable.zip(loginCapabilityObservable,
paletteObservable,
orgContactInfoObservable,
new Func3<LoginCapability, Palette, OrgContactInfo, CompositeLPLCPalette>() {
@Override
public CompositeLPLCPalette call(LoginCapability loginCapability, Palette palette, OrgContactInfo orgContactInfo) {
return new CompositeLPLCPalette(loginCapability, loginPreference, palette);
}
});
}
})
.zipWith(timerObservable, new Func2<CompositeLPLCPalette, Long, CompositeLPLCPalette>() {
@Override
public CompositeLPLCPalette call(CompositeLPLCPalette compositeLPLCPalette, Long aLong) {
return compositeLPLCPalette;
}
});
上面的代码可以工作,但我有几个问题:
1) 我强制执行最少 3 秒的方式是正确的方法吗?看起来有一个延迟运算符和计时器运算符,但不清楚我应该使用哪个。另外,我应该将计时器操作符与链的其余部分一起压缩吗?
2)如果我的 Intent 是如果可观察失败它应该只返回 null 而不是订阅者的 onError() 方法,那么我是否正确使用了 onErrorReturn() ?
3) 在 flatMap() 运算符中,我检查 loginPreference 是否为 null,是否有 null 激活代码或空激活代码,如果其中任何一个为 true,我不想运行其他 3 个可观察对象。我应该在 flatMap() 运算符之前使用不同的运算符,而不是将此逻辑添加到 flatMap() 吗?
最佳答案
是的,这是正确的方法。我建议将
flatMap
的内容提取为单独的方法,并出于逻辑和维护原因将 2 个 zip 运算符分开。我真的不喜欢在 observable 中包含 null,至少它与 RxJava 2 不兼容。但是考虑到需求,逻辑感觉是合理的。
嗯,你很好。
关于android - 使用 RxJava 确保任务至少需要一定的时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43924159/