加载更多关于改造和 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 并在旧流中发出新值,因为您当前的解决方案不会影响以前的订阅者,因为他们订阅了不同的流