Krz*_*ski 9 android rx-java retrofit2 rx-java2 android-room
我在我的应用程序中使用Room作为数据库层,并在网络调用中使用Retrofit - 无论是在房间还是改造中我都在使用RxJava2(这是我的第一个使用rxjava的项目,所以我在这方面仍然相当新手).要注入数据库,api等我正在使用Dagger 2.
我想进行网络呼叫并将响应从网络添加到数据库.当不需要再进行网络调用时 - 我想从数据库中获取数据.我在我的房间存储库中使用Maybe/Flowable时遇到问题.
这是道:
@Dao
public interface CoinDao {
@Query("SELECT * FROM coin")
Flowable<List<Coin>> getAllCoins();
@Insert
void insert(List<Coin> coins);
@Update
void update(Coin... coins);
@Delete
void delete(Coin... coins);
}
Run Code Online (Sandbox Code Playgroud)
这是我的存储库:
public class CoinRepository implements Repository {
private CoinMarketCapNetworkApi api;
private final CoinDao coinDao;
public CoinRepository(CoinMarketCapNetworkApi api, CoinDao coinDao) {
System.out.println("Creating CoinRepository");
this.api = api;
this.coinDao = coinDao;
}
@Override
public Flowable<List<Coin>> getCoinResults() {
System.out.println("getting coin results");
return getCoinResultsFromDatabase().switchIfEmpty(getCoinResultsFromNetwork())
}
@Override
public Flowable<List<Coin>> getCoinResultsFromNetwork() {
System.out.println("getting results from network");
return api.getCoins().doOnNext(new Consumer<List<Coin>>() {
@Override
public void accept(List<Coin> coins) throws Exception {
System.out.println("inserting to db");
coinDao.insert(coins);
}
});
}
@Override
public Flowable<List<Coin>> getCoinResultsFromDatabase() {
System.out.println("getting coins from database");
return coinDao.getAllCoins();
}
}
Run Code Online (Sandbox Code Playgroud)
我首先运行应用程序,仅通过网络呼叫填充数据库
@Override
public Flowable<List<Coin>> getCoinResults() {
return getCoinResultsFromNetwork();
}
Run Code Online (Sandbox Code Playgroud)
当执行网络调用时,数据已成功添加到数据库中 - 我再次运行应用程序,只从数据库获取数据并且它也是成功的 - 数据是从数据库中获取的.
@Override
public Flowable<List<Coin>> getCoinResults() {
return getCoinResultsFromDatabase();
}
Run Code Online (Sandbox Code Playgroud)
但是,当我现在尝试做这样的事情
return getCoinResultsFromDatabase.switchIfEmpty(getCoinResultsFromMemory));
Run Code Online (Sandbox Code Playgroud)
问题是每次执行switchIfEmpty并且每次执行"getCoinResultsFromMemory()"(即使数据库中的数据可用).
根据https://medium.com/google-developers/room-rxjava-acb0cd4f3757 我已经读过,当数据库中没有数据时,Flowable将不会发出任何内容,我应该使用Maybe.但是为什么即使数据库中有数据,getResultsFromMemory()也会返回空?在这种情况下我应该如何使用Maybe?
我试过将Flowable改为Maybe
Maybe<List<Coin>> getCoinResultsFromDatabase()
Run Code Online (Sandbox Code Playgroud)
并做这样的事情 - 从也许访问resutl并检查列表是否为空,但在这种情况下我不知道如何返回flowable:
public Flowable<List<Coin>> getCoinResults() {
getCoinResultsFromDatabase().subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<List<Coin>>() {
@Override
public void accept(List<Coin> coins) throws Exception {
System.out.println("returning coins from maybe" + coins.get(0).getId());
if (coins.isEmpty()) {
System.out.println("coin list is empty");
Flowable<List<Coin>> flowable = getCoinResultsFromNetwork();
} else {
Flowable<List<Coin>> flowable = getCoinResultsFromDatabase();
}
}
});
return flowable //how to access this flowable??
}
Run Code Online (Sandbox Code Playgroud)
也许我错过了一些东西,并且有一个更好,更清洁的解决方案.
您的代码存在一些问题:
1.看起来房间里Flowable<List<Coin>> getAllCoins()总是会返回一些值:要么是项目列表,要么是空列表,所以Maybe在这里没有帮助
2.在这段代码中
@Override
public Flowable<List<Coin>> getCoinResults() {
System.out.println("getting coin results");
return getCoinResultsFromDatabase().switchIfEmpty(getCoinResultsFromNetwork())
}
Run Code Online (Sandbox Code Playgroud)
getCoinResultsFromNetwork当你调用getCoinResults方法时,而不是当 flowable 为空时,就会调用它(这是普通的 java 方法调用)
您需要执行延迟呼叫。最终的解决方案可能如下所示
@Override
public Flowable<List<Coin>> getCoinResults() {
System.out.println("getting coin results");
return getCoinResultsFromDatabase()
.filter(list -> !list.isEmpty())
.switchIfEmpty(
Flowable.defer(() -> getCoinResultsFromNetwork()))
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4173 次 |
| 最近记录: |