Realm+RXJava+Retrofit 从网络或本地获取数据
Realm+RXJava+Retrofit fetch data from net or local
我参考了github上的项目来编写自己的代码
https://github.com/AlbertGrobas/Leaderboards
但还是发现了一些问题。
在 class 'LeaderboardDataService':
public Observable<Leaderboard> getLeaderboard(final String bracket, final boolean forceUpdate) {
final Observable<RealmLeaderboard> apiObservable = mClient.getApiClient().leaderboardObservable(bracket, Locale.getDefault().toString());
final Observable<RealmLeaderboard> dbObservable = mDAO.readLeaderboard(mHost, bracket);
return dbObservable.exists(new Func1<RealmLeaderboard, Boolean>() {
@Override
@DebugLog
public Boolean call(RealmLeaderboard leaderboard) {
return (leaderboard != null);
}
}).flatMap(new Func1<Boolean, Observable<RealmLeaderboard>>() {
@Override
@DebugLog
public Observable<RealmLeaderboard> call(Boolean inDB) {
return (inDB && !forceUpdate) ? dbObservable : apiObservable;
}
}).flatMap(new Func1<RealmLeaderboard, Observable<RealmLeaderboard>>() {
@Override
@DebugLog
public Observable<RealmLeaderboard> call(RealmLeaderboard leaderboard) {
if (leaderboard.getHost() == null) {
leaderboard.setBracket(bracket);
leaderboard.setHost(mHost);
}
return mDAO.writeLeaderboard(leaderboard, forceUpdate);
}
}).map(new Func1<RealmLeaderboard, Leaderboard>() {
@Override
@DebugLog
public Leaderboard call(RealmLeaderboard leaderboard) {
return realmToLeaderboard(leaderboard);
}
}); }
此函数用于确定从何处获取数据,
本地或网络。
有两个问题。
1、第一个exists函数判断realm中数据是否存在。
只有returns一个boolean,如果realm拿到数据,需要重新查询,
如果 realm 是空的,从 net 获取数据是没有问题的。
2.下一步,如果数据来自网络,更新存在的数据就可以了,
但如果数据来自领域,则无需更新这些数据。
该操作对来自领域的数据无用。
我对函数做了一些修改:
public Observable<List<ChhPost>> getPosts(final boolean forceUpdate) {
final String path = "getpostdata";
final Observable<RealmList<ChhPost>> apiObservable = getApiService().getApiClient().posts(path);
final Observable<RealmList<ChhPost>> dbObservable = getObservableDAO().readPosts();
return dbObservable.flatMap(new Func1<RealmList<ChhPost>, Observable<RealmList<ChhPost>>>() {
@Override
public Observable<RealmList<ChhPost>> call(final RealmList<ChhPost> chhPosts) {
boolean valid = chhPosts!=null && chhPosts.size()>0;
if(valid && !forceUpdate){
Observable<RealmList<ChhPost>> postsObservable = Observable.create(new Observable.OnSubscribe<RealmList<ChhPost>>() {
@Override
public void call(Subscriber<? super RealmList<ChhPost>> subscriber) {
subscriber.onNext(chhPosts);
subscriber.onCompleted();
}
});
return postsObservable;
}else{
return apiObservable;
}
}
}).flatMap(new Func1<RealmList<ChhPost>, Observable<RealmList<ChhPost>>>() {
@Override
public Observable<RealmList<ChhPost>> call(RealmList<ChhPost> topics) {
Loge.d("getPosts write to Db");
return mDAO.writePosts(topics, forceUpdate);
}
}).map(new Func1<RealmList<ChhPost>, List<ChhPost>>() {
@Override
public List<ChhPost> call(RealmList<ChhPost> topics) {
List<ChhPost> newTopics = new ArrayList<>();
for (ChhPost topic : topics) {
newTopics.add(topic);
}
return newTopics;
}
});
}
第一个问题好像解决了,但是第二个问题还存在。
做了一些研究,Rx onNext 函数只能有一个参数。
在这种情况下,我传递了我自己的 RealmList class。
class 是领域和改造以获取数据的模板 class。
问题是如何让write to realm函数知道
数据来自领域或改造,以避免无用的操作。
您可以使用 RealmList.isValid()
如果数据不由 Realm 管理,它将 return false:https://realm.io/docs/java/latest/api/io/realm/RealmList.html#isValid--
当前的 Javadoc 有点错误,我们会修复的:)
我参考了github上的项目来编写自己的代码 https://github.com/AlbertGrobas/Leaderboards 但还是发现了一些问题。 在 class 'LeaderboardDataService':
public Observable<Leaderboard> getLeaderboard(final String bracket, final boolean forceUpdate) {
final Observable<RealmLeaderboard> apiObservable = mClient.getApiClient().leaderboardObservable(bracket, Locale.getDefault().toString());
final Observable<RealmLeaderboard> dbObservable = mDAO.readLeaderboard(mHost, bracket);
return dbObservable.exists(new Func1<RealmLeaderboard, Boolean>() {
@Override
@DebugLog
public Boolean call(RealmLeaderboard leaderboard) {
return (leaderboard != null);
}
}).flatMap(new Func1<Boolean, Observable<RealmLeaderboard>>() {
@Override
@DebugLog
public Observable<RealmLeaderboard> call(Boolean inDB) {
return (inDB && !forceUpdate) ? dbObservable : apiObservable;
}
}).flatMap(new Func1<RealmLeaderboard, Observable<RealmLeaderboard>>() {
@Override
@DebugLog
public Observable<RealmLeaderboard> call(RealmLeaderboard leaderboard) {
if (leaderboard.getHost() == null) {
leaderboard.setBracket(bracket);
leaderboard.setHost(mHost);
}
return mDAO.writeLeaderboard(leaderboard, forceUpdate);
}
}).map(new Func1<RealmLeaderboard, Leaderboard>() {
@Override
@DebugLog
public Leaderboard call(RealmLeaderboard leaderboard) {
return realmToLeaderboard(leaderboard);
}
}); }
此函数用于确定从何处获取数据, 本地或网络。 有两个问题。 1、第一个exists函数判断realm中数据是否存在。 只有returns一个boolean,如果realm拿到数据,需要重新查询, 如果 realm 是空的,从 net 获取数据是没有问题的。 2.下一步,如果数据来自网络,更新存在的数据就可以了, 但如果数据来自领域,则无需更新这些数据。 该操作对来自领域的数据无用。
我对函数做了一些修改:
public Observable<List<ChhPost>> getPosts(final boolean forceUpdate) {
final String path = "getpostdata";
final Observable<RealmList<ChhPost>> apiObservable = getApiService().getApiClient().posts(path);
final Observable<RealmList<ChhPost>> dbObservable = getObservableDAO().readPosts();
return dbObservable.flatMap(new Func1<RealmList<ChhPost>, Observable<RealmList<ChhPost>>>() {
@Override
public Observable<RealmList<ChhPost>> call(final RealmList<ChhPost> chhPosts) {
boolean valid = chhPosts!=null && chhPosts.size()>0;
if(valid && !forceUpdate){
Observable<RealmList<ChhPost>> postsObservable = Observable.create(new Observable.OnSubscribe<RealmList<ChhPost>>() {
@Override
public void call(Subscriber<? super RealmList<ChhPost>> subscriber) {
subscriber.onNext(chhPosts);
subscriber.onCompleted();
}
});
return postsObservable;
}else{
return apiObservable;
}
}
}).flatMap(new Func1<RealmList<ChhPost>, Observable<RealmList<ChhPost>>>() {
@Override
public Observable<RealmList<ChhPost>> call(RealmList<ChhPost> topics) {
Loge.d("getPosts write to Db");
return mDAO.writePosts(topics, forceUpdate);
}
}).map(new Func1<RealmList<ChhPost>, List<ChhPost>>() {
@Override
public List<ChhPost> call(RealmList<ChhPost> topics) {
List<ChhPost> newTopics = new ArrayList<>();
for (ChhPost topic : topics) {
newTopics.add(topic);
}
return newTopics;
}
});
}
第一个问题好像解决了,但是第二个问题还存在。 做了一些研究,Rx onNext 函数只能有一个参数。 在这种情况下,我传递了我自己的 RealmList class。 class 是领域和改造以获取数据的模板 class。
问题是如何让write to realm函数知道 数据来自领域或改造,以避免无用的操作。
您可以使用 RealmList.isValid()
如果数据不由 Realm 管理,它将 return false:https://realm.io/docs/java/latest/api/io/realm/RealmList.html#isValid--
当前的 Javadoc 有点错误,我们会修复的:)