RxJava: распаковать объект - PullRequest
0 голосов
/ 29 апреля 2019

Я использую RxJava в своем проекте Android, и я рад этому. В настоящее время я использую его для того, чтобы сделать все мои методы DAO асинхронными и заставить интерфейс прослушивать их.

Но у меня есть большая проблема, то есть когда я получаю некоторые данные из базы данных, используя Observable<List<User>> getLists(), мне нужно использовать List<User> в моих ViewModels, но я не могу извлечь их из наблюдаемой.

Я хотел бы знать, каков общий подход к решению такого рода проблем? Я искал в Интернете, и люди сказали, что не рекомендуется извлекать объекты, но в этом случае, как я могу использовать данные из базы данных и в то же время по-прежнему позволять наблюдателям слушать?

Должен ли я создать другой метод, используя AsyncTask ??

Спасибо.

В моем UserRepo.java

public Observable<List<User>> getUsers() {
    return colisDao.getUsers();
}

В HomeScreenViewModel.java:

public List<User> getUsers() {
    return userRepo.getUsers(); // do not work because I need a List<User>
}

In HomeActivity.java:

UserListAdapter userListAdapter = new UserListAdapter(this,
            vm.getUsers());

Ответы [ 2 ]

3 голосов
/ 29 апреля 2019

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

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

Все типы RxJava2 предоставляют метод subscribe, который "уведомляет" источник данныхпо своей природе это лениво, так как здесь есть наблюдатель, который хочет получить данные, поэтому весь поток обработки данных, описанный с помощью операторов RxJava2, станет живым.

Самый безболезненный подход - изменить код HomeActivity's наthis:

vm.getUsers()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(userListAdapter::populateWithNewDataSet);

, при условии, что у адаптера будет упомянутый метод, который будет обновлять набор данных пользовательского интерфейса, используя что-то вроде notifyDataSetChanged() (или DiffUtil, например) внутри.

Благодаря этому теперь наблюдается источник данных, и каждый раз, когда происходит обновление, пользовательский интерфейс будет заполняться самыми последними данными.

PS: я только что продемонстрировал самый простой способ сделать это, но этоРазработчик должен разместить код, связанный с RxJava: будь то ViewModel, Activity или даже какой-то другой компонент.RxJava - это удобный инструмент, который может сделать сложный асинхронный поток простым, но проблема с RxJava возникает, когда от него зависит вся база кода.Затем кодовая база может быстро стать неуправляемой, хрупкой и жесткой, если инструмент использовался в неподходящем месте.

1 голос
/ 29 апреля 2019

Добавление к @AndreyIlyunin очень хорошего ответа. Вы также можете использовать MutableLivedata в своей Viewmodel, чтобы сохранить Список в viewmodel в качестве Livedata и наблюдать за изменениями в своей Activity.Google предлагает это как способ поддержки архитектуры MVVM.Что-то вроде:

В HomeScreenViewModel.java:

private final MutableLivedata<List<User>> users = new MutableLivedata<>();

public void getUsers() {
    return userRepo.getUsers()
       .subscribeOn(Schedulers.io())
       .observeOn(AndroidSchedulers.mainThread())
       .subscribe(this::onUsers)
}

private void onUsers(List<> list){
    users.setValue(list);
}

public MutableLivedata<List<User>> getUserList(){
    return users;
}

В HomeActivity.java, в onCreate () добавьте: vm.getUserList (). Наблюдайте (this, this :: onUserList);

и добавьте следующие методы в действие:

private void onUserList(List<> list){
    userListAdapter = new UserListAdapter(this,list);
}

, а затем из вызова вашей деятельности:

vm.getUsers();

Вызов getUsers () выполняется асинхронно в фоновом режиме,и вы получаете список пользователей реактивно.

...