仅第一次调用 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&lt;List&lt;CountryModel&gt;&gt; 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 方法的主要内容,如果未能解决你的问题,请参考以下文章