Baru-baru ini saya menjelajahi Arsitektur Android, yang baru-baru ini diperkenalkan oleh google. Dari Dokumentasi saya menemukan ini:
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
}
}
aktivitas dapat mengakses daftar ini sebagai berikut:
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
});
}
}
Pertanyaan saya adalah, saya akan melakukan ini:
dalam
loadUsers()
fungsi saya mengambil data secara asynchronous di mana saya pertama-tama akan memeriksa database (Room) untuk data ituJika saya tidak mendapatkan data di sana, saya akan membuat panggilan API untuk mengambil data dari server web.
Saya akan memasukkan data yang diambil ke dalam database (Room) dan memperbarui UI sesuai datanya.
Apa pendekatan yang direkomendasikan untuk melakukan ini?
Jika saya memulai Service
untuk memanggil API dari loadUsers()
metode, bagaimana saya bisa memperbarui MutableLiveData<List<User>> users
variabel dari itu Service
?
loadUsers()
pada dasarnya akan memanggil repo untuk mendapatkan informasi penggunaJawaban:
Saya berasumsi bahwa Anda menggunakan komponen arsitektur android . Sebenarnya tidak masalah ke mana pun Anda menelepon
service, asynctask or handler
untuk memperbarui data. Anda dapat memasukkan data dari layanan atau dari asynctask menggunakanpostValue(..)
metode. Kelas Anda akan terlihat seperti ini:private void loadUsers() { // do async operation to fetch users and use postValue() method users.postValue(listOfData) }
Sebagai
users
adalahLiveData
,Room
basis data bertanggung jawab untuk menyediakan data pengguna di mana pun dimasukkan.Note:
Dalam arsitektur seperti MVVM, repositori sebagian besar bertanggung jawab untuk memeriksa dan menarik data lokal dan data jarak jauh.sumber
LiveData
tidak memperbaruiusers.postValue(mUsers);
-> Tapi, apakah metode postValue MutableLiveData dapat menerima LiveData ???value
bukannyapostValue
. Terima kasih atas jawaban anda.Anda dapat menggunakan
MutableLiveData<T>.postValue(T value)
metode dari thread latar belakang.private void loadUsers() { // do async operation to fetch users and use postValue() method users.postValue(listOfData) }
sumber
.setValue()
tidak akan diizinkanJika aplikasi mengambil data pengguna di thread latar belakang, postValue (bukan setValue ) akan berguna.
Dalam metode loadData ada referensi ke objek "users" MutableLiveData. Metode loadData juga mengambil beberapa data pengguna baru dari suatu tempat (misalnya, repositori).
Sekarang, jika eksekusi berada di thread latar belakang, MutableLiveData.postValue () memperbarui pengamat luar dari objek MutableLiveData.
Mungkin sesuatu seperti ini:
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); } }); }
sumber
getUsers()
Metode repositori mungkin memanggil api untuk data yang async (mungkin memulai layanan atau asynctask untuk ini) dalam hal ini bagaimana cara mengembalikan List dari pernyataan kembaliannya?Lihat panduan arsitektur Android yang menyertai modul arsitektur baru seperti
LiveData
danViewModel
. Mereka membahas masalah ini secara mendalam.Dalam contoh mereka, mereka tidak memasukkannya ke dalam layanan. Lihatlah bagaimana mereka menyelesaikannya dengan menggunakan modul "repositori" dan Retrofit. Adendum di bagian bawah mencakup contoh yang lebih lengkap termasuk status jaringan komunikasi, kesalahan pelaporan, dll.
sumber
Jika Anda memanggil api Anda di Repository,
Dalam Repositori :
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; }
Di ViewModel
public LiveData<LoginResponseModel> getUser() { loginResponseModelMutableLiveData = repository.checkLogin(loginRequestModel); return loginResponseModelMutableLiveData; }
Dalam Aktivitas / Fragmen
loginViewModel.getUser().observe(LoginActivity.this, loginResponseModel -> { if (loginResponseModel != null) { Toast.makeText(LoginActivity.this, loginResponseModel.getUser().getType(), Toast.LENGTH_SHORT).show(); } });
Catatan: Menggunakan JAVA_1.8 lambda di sini, Anda dapat menggunakannya tanpa itu
sumber