Загрузить больше о модернизации и rxJava

Я пытаюсь загрузить сообщения из блога. Я использую 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, но строка в консоли пишет

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
                ));
    }
}

Это работает


person DrobyshevAlex    schedule 02.01.2017    source источник


Ответы (1)


Ваша проблема заключается в этом фрагменте кода:

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

Операторы над наблюдаемыми выполняют неизменяемые операции, что означает, что они всегда возвращают новый поток, который является модифицированной версией предыдущий. Это означает, что когда вы применяете оператор mergeWith, результат этого отбрасывается, так как вы его нигде не сохраняете. Самый простой способ исправить это — заменить старую переменную postList новым потоком.

Однако это не оптимальный способ сделать это. Вам следует взглянуть на Темы и выдать новые значения в старом потоке, поскольку ваше текущее решение не повлияет на предыдущих подписчиков, поскольку они подписались на другой поток.

person koperko    schedule 02.01.2017