Недавно я изучаю архитектуру Android, которую недавно представил Google. Из документации я нашел это:
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 async operation to fetch users
}
}
активность может получить доступ к этому списку следующим образом:
public class MyActivity extends AppCompatActivity {
public void onCreate(Bundle savedInstanceState) {
MyViewModel model = ViewModelProviders.of(this).get(MyViewModel.class);
model.getUsers().observe(this, users -> {
// update UI
});
}
}
Мой вопрос, я собираюсь сделать это:
в
loadUsers()
функции я получаю данные асинхронно, где я сначала проверю базу данных (комнату) на предмет этих данныхЕсли я не получу там данные, я сделаю вызов API для получения данных с веб-сервера.
Я вставлю полученные данные в базу данных (Room) и обновлю пользовательский интерфейс в соответствии с данными.
Какой рекомендуемый подход для этого?
Если я начну Service
вызывать API из loadUsers()
метода, как я могу обновить MutableLiveData<List<User>> users
переменную из этого Service
?
loadUsers()
основном вызывает репо для получения информации о пользователеОтветы:
Я предполагаю, что вы используете компоненты архитектуры Android . На самом деле не имеет значения, куда вы звоните,
service, asynctask or handler
чтобы обновить данные. Вы можете вставить данные из службы или из асинхронной задачи с помощьюpostValue(..)
метода. Ваш класс будет выглядеть так:private void loadUsers() { // do async operation to fetch users and use postValue() method users.postValue(listOfData) }
Как
users
этоLiveData
,Room
база данных отвечает за предоставление данных пользователей , где она установлена.Note:
В архитектуре, подобной MVVM, репозиторий в основном отвечает за проверку и извлечение локальных и удаленных данных.источник
LiveData
не обновляетсяusers.postValue(mUsers);
-> Но может ли метод postValue MutableLiveData принимать LiveData ???value
вместоpostValue
. Спасибо за Ваш ответ.Вы можете использовать
MutableLiveData<T>.postValue(T value)
метод из фонового потока.private void loadUsers() { // do async operation to fetch users and use postValue() method users.postValue(listOfData) }
источник
.setValue()
это невозможноЕсли приложение извлекает пользовательские данные в фоновом потоке, будет полезно postValue (а не setValue ).
В методе loadData есть ссылка на объект «пользователи» MutableLiveData. Метод loadData также извлекает некоторые свежие пользовательские данные откуда-то (например, из репозитория).
Теперь, если выполнение выполняется в фоновом потоке, MutableLiveData.postValue () обновляет внешних наблюдателей объекта MutableLiveData.
Может быть, примерно так:
private MutableLiveData<List<User>> users; . . . private void loadUsers() { // do async operation to fetch users ExecutorService service = Executors.newSingleThreadExecutor(); service.submit(new Runnable() { @Override public void run() { // on background thread, obtain a fresh list of users List<String> freshUserList = aRepositorySomewhere.getUsers(); // now that you have the fresh user data in freshUserList, // make it available to outside observers of the "users" // MutableLiveData object users.postValue(freshUserList); } }); }
источник
getUsers()
Метод репозитория может вызывать api для данных, которые являются асинхронными (для этого может быть запущена служба или асинхронная задача). В этом случае как он может вернуть список из своего оператора возврата?Ознакомьтесь с руководством по архитектуре Android, которое прилагается к модулям новой архитектуры, таким как
LiveData
иViewModel
. Они подробно обсуждают именно этот вопрос.В своих примерах они не помещают его в сервис. Посмотрите, как они решают эту проблему с помощью модуля «репозиторий» и дооснащения. Дополнения внизу включают более полные примеры, в том числе сообщения о состоянии сети, сообщения об ошибках и т. Д.
источник
Если вы вызываете свой api в репозитории, тогда
В репозитории :
public MutableLiveData<LoginResponseModel> checkLogin(LoginRequestModel loginRequestModel) { final MutableLiveData<LoginResponseModel> data = new MutableLiveData<>(); apiService.checkLogin(loginRequestModel) .enqueue(new Callback<LoginResponseModel>() { @Override public void onResponse(@NonNull Call<LoginResponseModel> call, @Nullable Response<LoginResponseModel> response) { if (response != null && response.isSuccessful()) { data.postValue(response.body()); Log.i("Response ", response.body().getMessage()); } } @Override public void onFailure(@NonNull Call<LoginResponseModel> call, Throwable t) { data.postValue(null); } }); return data; }
В ViewModel
public LiveData<LoginResponseModel> getUser() { loginResponseModelMutableLiveData = repository.checkLogin(loginRequestModel); return loginResponseModelMutableLiveData; }
В действии / фрагменте
loginViewModel.getUser().observe(LoginActivity.this, loginResponseModel -> { if (loginResponseModel != null) { Toast.makeText(LoginActivity.this, loginResponseModel.getUser().getType(), Toast.LENGTH_SHORT).show(); } });
Примечание. Используя лямбду JAVA_1.8, вы можете использовать без нее
источник