如何从另一个活动刷新ViewModel livedata

时间:2019-06-27 11:34:52

标签: java android

我正在开发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数据?

2 个答案:

答案 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。
  • 要使用API​​获取数据时,请致电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模型代码。 这样,在恢复活动之前始终会清除实时数据。