加载更多关于改造和 rxJava
Load more on retrofit and rxJava
我正在尝试从博客加载帖子。我用mosby + retrofit + rxjava.
public class PostRepository implements IPostRepository {
private Api api;
private long last_id = 0;
private Single<List<Post>> postList;
public PostRepository(Api api) {
this.api = api;
}
@Override
public Single<List<Post>> getList() {
this.load();
return postList;
}
private void load() {
Single<List<Post>> tmp;
Log.d(Configuration.DEBUG_TAG, "Loading " + last_id);
tmp = api.getPostList(last_id)
.map(posts -> {
ArrayList<Post> postList = new ArrayList<>();
for (PostResponse post : posts) {
if (last_id == 0 || last_id > post.id) {
last_id = post.id;
}
postList.add(new Post(
post.id,
post.thumb,
post.created_at,
post.title
));
}
return postList;
});
if (postList == null) {
postList = tmp;
} else {
postList.mergeWith(tmp);
}
}
@Override
public Single<Post> getDetail(long id) {
return api.getPost(id)
.map(postResponse -> new Post(
postResponse.id,
postResponse.thumb,
postResponse.created_at,
postResponse.title,
postResponse.body
));
}
}
和api
public interface Api {
@GET("posts")
Single<PostListResponse> getPostList(@Query("last_id") long last_id);
@GET("post/{id}")
Single<PostResponse> getPost(@Path("id") long id);
}
第一次查询网站就可以了。 https://site/posts?last_id=0
但是第二个 运行 函数 getList 不起作用。
我总是得到与 last_id = 0 相同的 get 查询,但控制台中的行写
D/App: Loading 1416
D/App: 1416
D/OkHttp: --> GET https://site/posts?last_id=0 http/1.1
如果我写
tmp = api.getPostList(1000)
然后我得到真正的查询字符串https://site/posts?last_id=1000
更新
我重写代码库。
public class PostRepository implements IPostRepository {
private Api api;
private long last_id = 0;
private List<Post> postList = new ArrayList<>();
private Observable<List<Post>> o;
public PostRepository(Api api) {
this.api = api;
}
@Override
public Single<List<Post>> getList() {
return load();
}
private Single<List<Post>> load() {
return api.getPostList(last_id)
.map(posts -> {
for (PostResponse post : posts) {
if (last_id == 0 || last_id > post.id) {
last_id = post.id;
}
postList.add(new Post(
post.id,
post.thumb,
post.created_at,
post.title
));
}
return postList;
});
}
@Override
public Single<Post> getDetail(long id) {
return api.getPost(id)
.map(postResponse -> new Post(
postResponse.id,
postResponse.thumb,
postResponse.created_at,
postResponse.title,
postResponse.body
));
}
}
工作正常
您的问题出在这段代码中:
if (postList == null) {
postList = tmp;
} else {
postList.mergeWith(tmp); // here
}
Operators on observables 正在执行 immutable 操作,这意味着它总是 returns new stream 这是前一个的修改版本。这意味着,当您应用 mergeWith
运算符时,结果将被丢弃,因为您没有将它存储在任何地方。最容易解决这个问题的方法是用新流替换旧的 postList 变量。
但是,这不是执行此操作的最佳方式。您应该查看 Subjects 并在旧流中发出新值,因为您当前的解决方案不会影响以前的订阅者,因为他们订阅了不同的流
我正在尝试从博客加载帖子。我用mosby + retrofit + rxjava.
public class PostRepository implements IPostRepository {
private Api api;
private long last_id = 0;
private Single<List<Post>> postList;
public PostRepository(Api api) {
this.api = api;
}
@Override
public Single<List<Post>> getList() {
this.load();
return postList;
}
private void load() {
Single<List<Post>> tmp;
Log.d(Configuration.DEBUG_TAG, "Loading " + last_id);
tmp = api.getPostList(last_id)
.map(posts -> {
ArrayList<Post> postList = new ArrayList<>();
for (PostResponse post : posts) {
if (last_id == 0 || last_id > post.id) {
last_id = post.id;
}
postList.add(new Post(
post.id,
post.thumb,
post.created_at,
post.title
));
}
return postList;
});
if (postList == null) {
postList = tmp;
} else {
postList.mergeWith(tmp);
}
}
@Override
public Single<Post> getDetail(long id) {
return api.getPost(id)
.map(postResponse -> new Post(
postResponse.id,
postResponse.thumb,
postResponse.created_at,
postResponse.title,
postResponse.body
));
}
}
和api
public interface Api {
@GET("posts")
Single<PostListResponse> getPostList(@Query("last_id") long last_id);
@GET("post/{id}")
Single<PostResponse> getPost(@Path("id") long id);
}
第一次查询网站就可以了。 https://site/posts?last_id=0
但是第二个 运行 函数 getList 不起作用。 我总是得到与 last_id = 0 相同的 get 查询,但控制台中的行写
D/App: Loading 1416
D/App: 1416
D/OkHttp: --> GET https://site/posts?last_id=0 http/1.1
如果我写
tmp = api.getPostList(1000)
然后我得到真正的查询字符串https://site/posts?last_id=1000
更新 我重写代码库。
public class PostRepository implements IPostRepository {
private Api api;
private long last_id = 0;
private List<Post> postList = new ArrayList<>();
private Observable<List<Post>> o;
public PostRepository(Api api) {
this.api = api;
}
@Override
public Single<List<Post>> getList() {
return load();
}
private Single<List<Post>> load() {
return api.getPostList(last_id)
.map(posts -> {
for (PostResponse post : posts) {
if (last_id == 0 || last_id > post.id) {
last_id = post.id;
}
postList.add(new Post(
post.id,
post.thumb,
post.created_at,
post.title
));
}
return postList;
});
}
@Override
public Single<Post> getDetail(long id) {
return api.getPost(id)
.map(postResponse -> new Post(
postResponse.id,
postResponse.thumb,
postResponse.created_at,
postResponse.title,
postResponse.body
));
}
}
工作正常
您的问题出在这段代码中:
if (postList == null) {
postList = tmp;
} else {
postList.mergeWith(tmp); // here
}
Operators on observables 正在执行 immutable 操作,这意味着它总是 returns new stream 这是前一个的修改版本。这意味着,当您应用 mergeWith
运算符时,结果将被丢弃,因为您没有将它存储在任何地方。最容易解决这个问题的方法是用新流替换旧的 postList 变量。
但是,这不是执行此操作的最佳方式。您应该查看 Subjects 并在旧流中发出新值,因为您当前的解决方案不会影响以前的订阅者,因为他们订阅了不同的流