gpt4 book ai didi

android - 数据更改时不会调用 LiveData onChanged

转载 作者:行者123 更新时间:2023-12-02 15:11:56 33 4
gpt4 key购买 nike

我刚开始使用 LiveDataViewModels,而且我不完全了解数据是如何更新的。

根据Android Dev site :

Instead of updating the UI every time the app data changes, your observer can update the UI every time there's a change.

这句话对我来说没有意义。我使用的是 Sqlite 数据库(没有 Room),并且在 ViewModelgetItems() 方法中异步获取数据。这是否意味着当数据库中添加或更新数据时,LiveData 会自动检测到它并调用 onChange

根据 Android 开发网站,它表示要在 onCreate 中开始观察 LiveData 对象。在使用 LiveData 之前,我通过查询数据库然后调用 notifyDataSetChanged() 来刷新 onResume 中的数据。

我现在的这段代码在 Fragment 加载时显示数据,但如果我删除数据库或向数据库添加新数据,UI 不会反射(reflect)更改。我只是认为我对 LiveData 的工作原理没有基本的了解,而且我在任何地方都找不到好的解释。

帮助我 StackOverflow,你是我唯一的希望。

public class MyViewModel extends AndroidViewModel {
private MutableLiveData<List<String>> items;
private Application application;

public MyViewModel(@NonNull Application application) {
super(application);
this.application = application;
}

public MutableLiveData<List<String>> getItems() {
if (items == null) {
items = new MutableLiveData<>();
getItems();
}
return items;
}

private void getItems() {
List<String> items = GetItems(); //async process

this.items.setValue(items)
}
}

public class ListFragment extends Fragment {

@Override
public void onCreate(final Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

MyViewModel model = ViewModelProviders.of(getActivity()).get(MyViewModel.class);

final Observer<List<String>> observer = new Observer<List<String>>() {
@Override
public void onChanged(List<String> items) {
//update UI
}
};

model.getItems().observe(this, observer);
}

}

最佳答案

如果 private MutableLiveData<List<String>> items,则您仅检索项目一次尚未初始化:

public MutableLiveData<List<String>> getItems() {
if (items == null) {
items = new MutableLiveData<>();
getItems();// it's called only once
}
return items;
}

解决此问题的一种方法是使用 ContentObserver对于您的数据:

...
private final ContentObserver contentObserver = new ContentObserver(new Handler()) {
@Override
public void onChange(boolean selfChange) {
// if there're any changes then perform the request and update the UI
getItems();
}
};
...

不要忘记注册它以获得数据库更改的通知:

...
contentResolver.registerContentObserver(<your data content uri>, true, contentObserver);
...

我还建议创建一个单独的 Repository负责数据检索的层可能如下所示:

...
private final ContentObserver contentObserver = new ContentObserver(new Handler()) {
@Override
public void onChange(boolean selfChange) {
// if there're any changes then perform the request and update the UI
getItems();
}
};

public LiveData<List<String>> getItems() {
return new MutableLiveData<String>() {
@Override
public void onActive() {
// your async operation here
new Thread({
List<String> items = db.getItems();
postValue(items);
}).start();

contentResolver.registerContentObserver(<your data content uri>, true, contentObserver);
}

@Override
public void onInactive() {
contentResolver.unregisterContentObserver(contentObserver);
}
}
return liveData;
}
...

那么,你的ViewModel需要注入(inject)存储库对象,因此需要 ViewModelFactory构建 ViewModel 的实例但整体用法看起来与此类似:

public class MyViewModel extends AndroidViewModel {   
...
public MutableLiveData<List<String>> getItems() {
dataRepository.getItems();
}
...
}

要获取更多信息,请阅读 Guide to app architecture

关于android - 数据更改时不会调用 LiveData onChanged,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58827286/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com