Soru Bir ViewModel'in LiveData'sını arka plan hizmetinden ve Update UI'den nasıl güncellerim


Son zamanlarda Google tarafından yakın zamanda tanıtılan Android Mimarisini keşfediyorum. İtibaren belgeleme Bunu buldum:

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

aktivite bu listeye aşağıdaki gibi erişebilir:

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

Benim sorum, loadUsers() Bu veriler için veri tabanını (Oda) kontrol edeceğim veriyi eşzamansız olarak getiriyorum. Verileri alamıyorsam, verileri web sunucusundan almak için bir API çağrısı yapacağım. Sonra getirilen verileri veri tabanına (Oda) yerleştiririm ve veriye göre UI'yi güncellerim. Bunu yapmak için önerilen yaklaşım nedir?

Eğer başlarsam Service API’yı loadUsers() yöntemini nasıl güncelleyebilirim MutableLiveData<List<User>> users bundan değişken Service?


33
2018-05-26 15:15


Menşei


Her şeyden önce, bir Deposu kaçırıyorsunuz. ViewModel'iniz herhangi bir veri yükleme görevi gerçekleştirmemelidir. Bunun dışında, kullandığınız Odadan bu yana, Hizmetinizin LiveData'yı doğrudan ViewModel'de güncellemesi gerekmiyor. ViewModelData'niz yalnızca Oda'ya eklenmeli ve Odadan güncellemeler alınmalıdır (Service inserts data'dan sonra). Ancak, mutlak en iyi mimari için, bu sayfanın altından NetworkBoundResource sınıf uygulamasına bakın: developer.android.com/topic/libraries/architecture/guide.html - Marko Gajić
öneri için teşekkür ederim :) - CodeCameo
Reuters sınıfının, ROOM'u veya android mimarisi bileşenlerini açıklayan resmi olmayan dokümanlarda belirtilmemiş olması - jonney


Cevaplar:


Kullandığını farz ediyorum android mimari bileşenleri. Aslında nerede aradığınız önemli değil service, asynctask or handler verileri güncellemek için Verileri servisten veya asenkronizasyondan postValue(..) yöntem. Sınıfın şöyle görünürdü:

private void loadUsers() {
    // do async operation to fetch users and use postValue() method
    users.postValue(listOfData)
}

Olarak users olduğu LiveData, Room Veri tabanı, nereye eklendiyse kullanıcı verilerini sağlamaktan sorumludur.

Note: MVVM benzeri mimaride, depo, çoğunlukla yerel verileri ve uzak verileri kontrol etmek ve çekmekle sorumludur.


15
2018-05-31 19:54



"Java.lang.IllegalStateException: Yukarıdaki ana dizideki veritabanına erişemiyorum" diyerek yukarıdaki gibi db yöntemlerini çağırırken, neyin yanlış olabileceğini söyleyebilir misiniz? - pcj
Ben kullanıcı arayüzünde iken veritabanını arka planda güncelleyen evernote-job kullanıyorum. Fakat LiveData güncellenmiyor - Akshay Chordiya
users.postValue(mUsers); -> Ancak, MutableLiveData'nın postValue yöntemi, LiveData'yı kabul edebilir mi ??? - Cheok Yan Cheng
Benim hatam kullaniyordu value yerine postValue. Cevabınız için teşekkürler. - Hesam
@pcj ya bir iş parçasında oda işlemini yapmalı veya ana iş parçasındaki işlemleri etkinleştirmelisiniz - daha fazla cevap için google. - kilokahn


Lütfen canlı verileri kullan postValue (..) arka plan iş parçacığı yöntemi.

private void loadUsers() {
    // do async operation to fetch users and use postValue() method
   users.postValue(listOfData)
}

34
2017-07-30 12:46



Hatırlamak için, postValue (), LiveData'da korunur, ancak MutableLiveData'da geneldir - Long Ranger


... loadUsers () işlevinde, verileri eşzamansız olarak getiriyorum ...   API'yi loadUsers () yönteminden çağırmak için bir Hizmet başlatırsam, nasıl yapılır?   MutableLiveData> kullanıcı değişkenini bundan güncelleyebilir miyim?   Hizmet?

Uygulama, arka plan iş parçacığında kullanıcı verilerini getiriyorsa, postValue (ziyade setValue) yararlı olacaktır.

LoadData yönteminde MutableLiveData "users" nesnesine bir başvuru var. LoadData yöntemi ayrıca bazı yeni kullanıcı verilerini bir yerden (örneğin bir depodan) alır.

Şimdi, yürütme bir arka plan iş parçacığı üzerindeyse, MutableLiveData.postValue (), MutableLiveData nesnesinin gözlemcileri dışında güncelleştirir.

Belki böyle bir şey:

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

}

11
2018-06-08 20:21



Depo en getUsers() yöntem, bu durumda eşzamanlı olmayan (bu bir hizmet veya asenkronizasyon başlatabilir) veriler için bir api çağırabilir. Bu durumda Listeyi iade ifadesinden nasıl geri döndürebilir? - CodeCameo
Belki de LiveData nesnesini bir argüman olarak alabilir. (Repository.getUsers (kullanıcılar) gibi bir şey). Sonra depo yöntemi users.postValue kendisini çağırır. Ve, bu durumda, loadUsers yönteminin bir arka plan iş parçacığına bile gerek duymaz. - albert c braun
Cevabınız için teşekkür ederiz .... ancak, Depolama için bir Room DB kullanıyorum ve DAO bir LiveData <Object> döndürüyor ... LiveData'yı bir MutableLiveData <Object> 'a nasıl dönüştürebilirim? - kilokahn
Room's DAO'nun gerçekten MutableLiveData nesnelerini ele almayı planladığını düşünmüyorum. DAO, altta yatan db'ye ilişkin bir değişikliği size bildirir, ancak, DB'deki değeri değiştirmek isterseniz, DAO'nun yöntemlerini çağırırsınız. Belki de burada tartışma yararlıdır: stackoverflow.com/questions/50943919/... - albert c braun


Bir göz atın Android mimarisi rehberi gibi yeni mimari modüllere eşlik ediyor LiveData ve ViewModel. Bu konuyu derinlemesine tartışıyorlar.

Örneklerinde bir servise koymuyorlar. Bir "depo" modülü ve Güçlendirme kullanarak nasıl çözdüklerine bakın. Alttaki ekler arasında iletişim ağı durumu, raporlama hataları vb. Dahil olmak üzere daha eksiksiz örnekler bulunur.


4
2018-06-05 18:22





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

Probleminiz için çok iyi cevaplar var. Yanıtı veritabanınıza nasıl kaydedebileceğinizi ve LiveData kullanarak UI'yi nasıl güncelleyeceğinizi görmek için aşağı doğru ilerleyin.

enter image description here


2
2018-04-17 21:02