我正在开发android应用程序,我想从第二个活动中刷新viewModel livedata。回到第一个活动时,数据不会刷新。
FirstActivity:
mViewModel = ViewModelProviders.of(this).get(MenuViewModel.class);
mViewModel.getMenus().observe(this, menuResponse -> {
if (menuResponse != null) {
resMenus.addAll(menuResponse.getMenus());
progressBar.setVisibility(View.GONE);
mAdapter.notifyDataSetChanged();
}
});
MenuViewModel:
public class MenuViewModel extends AndroidViewModel {
private MutableLiveData<MenuResponse> restMenuData;
private MenusRepository mRepository;
public MainActivityViewModel(@NonNull Application application) {
super(application);
mRepository = MenusRepository.getInstance(application);
restMenuData = mRepository.getMenus();
}
public LiveData<MenuResponse> getMenus() {
return restMenuData;
}
}
MenusRepository
private MenusRepository(Context context) {
apiRequest= RetrofitInstance.getInstance(context).getApiRequest();
}
public synchronized static MenusRepository getInstance(Context context) {
if (projectRepository == null) {
projectRepository = new MenusRepository(context);
}
return projectRepository;
}
public MutableLiveData<MenuResponse> getMenus() {
final MutableLiveData<MenuResponse> data = new MutableLiveData<>();
apiRequest.getMenus().enqueue(new Callback<MenuResponse>() {
@Override
public void onResponse(@NonNull Call<MenuResponse> call, @NonNull Response<MenuResponse> response) {
if (response.isSuccessful() && response.body() != null) {
data.setValue(response.body());
}
}
@Override
public void onFailure(@NonNull Call<MenuResponse> call, @NonNull Throwable t) {
data.setValue(null);
}
});
return data;
}
SecondActivity:
MenuViewModel mViewModel = ViewModelProviders.of(Objects.requireNonNull(SecondActivity.this)).get(MenuViewModel.class);
mViewModel.getMenus();
// This line not refresh menus
除了从viewmodel刷新数据外,我返回旧数据。 如何以最佳做法刷新ViewModel数据?
答案 0 :(得分:1)
MenusRepository.getMenus()
方法为每个调用创建LiveData
的新实例。这不是正确的解决方法。
您应该只有LiveData
的一个实例,并且有不同的对象订阅(活动,viewModel等)。
您可以做的是-创建一个MenusRepository
的单例(我想您已经完成了)。仅创建MutableLiveData
的一个实例,并使用它来更新数据。
class MenusRepository {
private val liveData = MutableLiveData<MenuResponse>()
fun getMenus() {
// Your api call. Do not create a new instance of the livedata.
}
fun menus(): LiveData<MenuResponse> {
return liveData
}
fun update(data: MenuResponse) {
liveData.post(data)
}
这段代码在Kotlin中,但它也类似地适用于Java。
您可以使用update
方法将更新发布到liveData。更新时,所有观察者都会收到新数据。使用MenusRepository.menus()
访问ViewModel中的LiveData。
更新
您的MenuRepository
类可能是这样的。
private final MutableLiveData<MenuResponse> liveData = new MutableData<>();
private MenusRepository(Context context) {
apiRequest= RetrofitInstance.getInstance(context).getApiRequest();
}
public synchronized static MenusRepository getInstance(Context context) {
if (projectRepository == null) {
projectRepository = new MenusRepository(context);
}
return projectRepository;
}
public MutableLiveData<MenuResponse> loadMenus() {
apiRequest.getMenus().enqueue(new Callback<MenuResponse>() {
@Override
public void onResponse(@NonNull Call<MenuResponse> call, @NonNull Response<MenuResponse> response) {
if (response.isSuccessful() && response.body() != null) {
liveData.setValue(response.body());
}
}
@Override
public void onFailure(@NonNull Call<MenuResponse> call, @NonNull Throwable t) {
liveData.setValue(null);
}
});
}
public LiveData<MenuResponse> getMenus() {
return liveData;
}
public void updateData(response: MenuResponse) {
liveData.postValue(response);
}
menuRepository.update()
方法。这会将数据发布到LiveData,这将更新其所有观察者,即。 ViewModel。menuRepository.loadMenu()
。menuRepository.getMenus()
获取LiveData并附加您的观察者。由于MenuRepository
是单例,因此LiveData
只有一个实例。当您发布对此LiveData实例的更新时,所有观察者都将收到新数据。
答案 1 :(得分:0)
public class MenuViewModel extends AndroidViewModel {
private MutableLiveData<MenuResponse> restMenuData;
private MenusRepository mRepository;
public MainActivityViewModel(@NonNull Application application) {
super(application);
mRepository = MenusRepository.getInstance(application);
restMenuData = mRepository.getMenus();
}
public LiveData<MenuResponse> getMenus() {
restMenuData = new MutableLiveData<>();
return restMenuData;
}
}
如上所述,更改View模型代码。 这样,在恢复活动之前始终会清除实时数据。