0

我正在尝试从博客加载帖子。我使用 mosby + 改造 + 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
                ));
    }
}

这是工作

4

1 回答 1

2

您的问题在于此代码片段:

if (postList == null) {
    postList = tmp;
} else {
    postList.mergeWith(tmp); // here
}

observables 上的操作符正在执行不可变操作,这意味着它总是返回新流,它是前一个流的修改版本。这意味着,当您应用mergeWith运算符时,此结果将被丢弃,因为您没有将其存储在任何地方。最容易解决这个问题的方法是用新的流替换旧的 postList 变量。

但是,这不是执行此操作的最佳方式。您应该查看主题并在旧流中发出新值,因为您当前的解决方案不会影响以前的订阅者,因为他们订阅了不同的流

于 2017-01-02T22:41:25.277 回答