Android ViewModel: Должен ли я "позаимствовать" метод наблюдений () из LiveData, как в официальном примере?

При работе с ViewModels View соблюдает ViewModel. Он должен зарегистрироваться в качестве наблюдателя. В официальном учебнике Google эта регистрация делегирована observe() метод LiveData объект.

public class MyViewModel extends ViewModel {
    private MutableLiveData<List<User>> users;
    public LiveData<List<User>> getUsers() {
        if (users == null) {
            users = new MutableLiveData<List<Users>>();
            loadUsers();
        }
        return users;
    }

    private void loadUsers() {
        // Do an asynchronous operation to fetch users.
    }
}

public class MyActivity extends AppCompatActivity {
    public void onCreate(Bundle savedInstanceState) {
        // Create a ViewModel the first time the system calls an activity's onCreate() method.
        // Re-created activities receive the same MyViewModel instance created by the first activity.

        MyViewModel model = ViewModelProviders.of(this).get(MyViewModel.class);
        model.getUsers().observe(this, users -> {
            // update UI
        });
    }
}

Метод getUsers() возвращает LiveData сам объект Это observe() Метод используется для регистрации наблюдателя. Вид не соблюдает ViewModel но часть его реализации.

Теперь это лучшая практика при работе с ViewModels не наблюдать за собой, но частями их реализации в виде LiveData объекты? Или это введение низкого качества?

2 ответа

На основании ответа Криса я даю свой ответ. Я думаю, что руководство не является лучшей практикой по той простой причине, что объект не должен раскрывать свою внутреннюю реализацию. Основываясь на аргументации Криса, я искал возможность получить инкапсуляцию без потери названных функций. Результатом является метод observerUsers() который делегирует LiveData объект внутренне.

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        MainActivityViewModel model = ViewModelProviders.of(this).get(MainActivityViewModel.class);
        model.observeUsers(this,
                new Observer<List<User>>() {
                    @Override
                    public void onChanged(@Nullable List<User> users) {
                        updateUI();
                    }
                }
        );
    }

    void updateUI() {

    }

    static class MainActivityViewModel extends ViewModel {
        private MutableLiveData<List<User>> users;

        public void observeUsers(@NonNull LifecycleOwner owner,
                                 @NonNull Observer<List<User>> observer) {
            getUsers().observe(owner, observer);
        }

        private LiveData<List<User>> getUsers() {
            if (users == null) {
                users = new MutableLiveData<>();
                loadUsers();
            }
            return users;
        }

        private void loadUsers() {
            // Do an asynchronous operation to fetch users.
        }
    }

    static class User {
    }

}

Еще List<User> выставляет внутреннюю реализацию. Это может быть улучшено до класса Users,

Я помещаю все в один файл и использую внутренний статический класс. Это не означает лучшую практику. Это было просто, чтобы иметь возможность быстро редактировать все в одном файле. Особенно модель User принадлежит в свой собственный файл, в то время как я часто помещаю ViewModel в View класс, к которому это относится

Моя вторая точка зрения на критику совпадает с тем, что ViewModel сам соблюдает базовую модель. В этом случае метод наблюдателя onChange() является очень общим и требует очень общего метода обновления, такого как updateUI(), Возможно, вы захотите наблюдать более конкретные события модели, чтобы сделать конкретные обновления.

Я бы сказал, что да, для ViewModel лучше всего выставлять свои данные через некоторую форму Observable, будь то LiveData или что-то вроде RX Observable.

Это отличается от других архитектур, таких как MVP, где презентатор обычно имеет ссылку на представление, которое вызывается при изменении чего-либо. Рекомендации довольно специфичны в отношении того, на что должна ссылаться ViewModel.

A ViewModel must never reference a view, Lifecycle, or any class that may hold a reference to the activity context.

Предоставляя ваши данные в качестве наблюдаемой через ViewModel, это означает, что представления могут приходить и уходить, и после подписки получит самые последние данные и любые последующие обновления. Снова руководящие принципы имеют некоторые детали.

If the activity is re-created, it receives the same MyViewModel instance that was created by the first activity. When the owner activity is finished, the framework calls the ViewModel objects's onCleared() method so that it can clean up resources

https://developer.android.com/topic/libraries/architecture/viewmodel.html

Другие вопросы по тегам