仅第一次调用 LiveData onChanged 方法
Posted
技术标签:
【中文标题】仅第一次调用 LiveData onChanged 方法【英文标题】:LiveData onChanged method called only first time 【发布时间】:2018-10-02 12:17:19 【问题描述】:我有一个简单的应用程序,它可以轮询服务以在回收站视图中显示国家/地区列表。在这里,只要国家/地区列表有任何变化,我就会使用 LiveData 更新回收站视图。麻烦的是,LiveData 的 onChanged 方法仅在第一次调用 setValue 时才被调用。但在那之后,如果数据有任何进一步的变化,onChanged 就不会被调用??
以下是我的代码以获取更多信息 -
CountryListFragment
//Setup observer
Observer<List<CountryModel>> myObserver = new Observer<List<CountryModel>>()
@Override
public void onChanged(@Nullable List<CountryModel> countryModels)
mCountryList = countryModels;
//Update recyclerview
myAdapter.updateRecyclerView(mCountryList);
;
//Set Observer for Viewmodel
countryViewModel.getmCountryList().observe(this,myObserver);
CountryViewModel
公共类 CountryViewModel 扩展 androidViewModel 私有 MutableLiveData> mCountryList; 私人 MyRetrofitClient myRetrofitClient;
public CountryViewModel(@NonNull Application application)
super(application);
public void init()
mCountryList = new MutableLiveData<>();
myRetrofitClient = new MyRetrofitClient();
**mCountryList = myRetrofitClient.getCountryList(); //This works**
pollCountryList();
//Create polling request for every 10 secs
private void pollCountryList()
final Handler mHandler = new Handler();
new Thread(new Runnable()
@Override
public void run()
for (int i=0; i<30;i++)
try
Thread.sleep(10000);
catch (InterruptedException e)
e.printStackTrace();
//Call API on main thread
mHandler.post(new Runnable()
@Override
public void run()
**myRetrofitClient.getCountryList(); //NOT CALLING ONCHANGED??**
);
).start();
public MutableLiveData<List<CountryModel>> getmCountryList()
return mCountryList;
MyRetrofitClient.getCountryList()
public MutableLiveData<List<CountryModel>> getCountryList() final MutableLiveData<List<CountryModel>> lstResult = new MutableLiveData<>(); MockServiceInterface serviceInterface = mRetrofit.create(MockServiceInterface.class); Call<List<CountryModel>> countryList = serviceInterface.getCountryList(); countryList.enqueue(new Callback<List<CountryModel>>() @Override public void onResponse(Call<List<CountryModel>> call, Response<List<CountryModel>> response) if (response.isSuccessful()) List<CountryModel> lstResponse = response.body(); lstResult.setValue(lstResponse); else System.out.print(response.errorBody());
@Override
public void onFailure(Call<List<CountryModel>> call, Throwable t)
t.printStackTrace();
);
return lstResult;
谢谢!
编辑:
一些额外的观察- 当我在 CountryViewModel 中调用 MutableLiveData 实例 (mCountryList) 的 setValue 方法时,它每次都会调用 onChanged 方法。
但是在 MyRetrofitClient 的情况下它有所不同。在 MyRetrofitClient.getCountryList() 中第一次调用 setValue 时,它会调用 onChanged 方法。但后来就没有了。
【问题讨论】:
【参考方案1】:抱歉,一开始我误解了问题。
您没有收到更改,因为您从未在 mCountryList
上调用过 setValue
。
方法 getCountryList()
正在返回新对象 MutableLiveData<List<CountryModel>> lstResult
它被调用的所有内容,没有人观察。
解决方案:
不是用getCountryList
返回MutableLiveData
对象,而是在onResponse()
中设置mCountryList
。
代码
public void init()
mCountryList = new MutableLiveData<>();
myRetrofitClient = new MyRetrofitClient();
myRetrofitClient.getCountryList();
pollCountryList();
public LiveData<List<CountryModel>> getCountryListener()
return mCountryList;
public void getCountryList()
MockServiceInterface serviceInterface = mRetrofit.create(MockServiceInterface.class);
Call<List<CountryModel>> countryList = serviceInterface.getCountryList();
countryList.enqueue(new Callback<List<CountryModel>>()
@Override
public void onResponse(Call<List<CountryModel>> call, Response<List<CountryModel>> response)
if (response.isSuccessful())
List<CountryModel> lstResponse = response.body();
mCountryList.setValue(lstResponse);
else
System.out.print(response.errorBody());
@Override
public void onFailure(Call<List<CountryModel>> call, Throwable t)
t.printStackTrace();
);
使用getCountryListener()
观察。
活动:
countryViewModel.getCountryListener().observe(this,myObserver);
【讨论】:
添加新方法 getCountryListener() 用于观察。 是的,你是对的。但是,我没有在 getCountryList 方法中分配 mCountryList,而是将 MutableLiveData lstResult 的初始化代码移到了 MyRetrofitClient 类的 init 方法中。因此在初始化期间只创建了一个 MutableLiveData 实例。这被分配给 mCountryList 并且以后每次调用它的 setValue 时,相应的 onChanged 也会被调用。谢谢!以上是关于仅第一次调用 LiveData onChanged 方法的主要内容,如果未能解决你的问题,请参考以下文章
onChanged LiveData 未调用,RecyclerView 保持为空
Room:来自 Dao 的 LiveData 将在每次更新时触发 Observer.onChanged,即使 LiveData 值没有变化