从另一个线程刷新RecyclerView导致错误

时间:2018-10-23 08:08:04

标签: android android-recyclerview android-thread

我有在另一个活动中已更新的项目的数组列表,当我从活动中返回时,我想使用全新的ArrayList()刷新recyclerview。为了避免滞后,我将刷新放置在其他Runnable线程上,并放置了ProgressBar而不是RecyclerView。

在新线程中,此方法称为内部适配器(recyclerViewAdapter.adapterRefreshFoods()

fun adapterRefreshFoods(filteredList: ArrayList<Food>){
        if (!filteredList.isEmpty()){
            foodList = filteredList
            notifyDataSetChanged()
        }
    }

这导致以下异常。 (当我在UIThread中刷新它时,效果很好)

java.lang.IllegalStateException: Cannot call this method while RecyclerView is computing a layout or scrolling android.support.v7.widget.RecyclerView

3 个答案:

答案 0 :(得分:1)

除了主线程/ UI线程之外,您永远不要从其他线程访问UI元素。您可以使用AsyncTask将数据加载到后台,并使用publishProgress()onProgressUpdate()连续更新UI。

    new AsyncTask<Void, List<YourDataClass>, List<YourDataClass>>(){
        @Override
        protected List<YourDataClass> doInBackground(Void... voids) {
            // Fetch data here and call publishProgress() to invoke
            // onProgressUpdate() on the UI thread.
            publishProgress(dataList);
            return dataList;
        }

        @Override
        protected void onProgressUpdate(List<YourDataClass>... values) {
            // This is called on the UI thread when you call 
            // publishProgress() from doInBackground()
        }

        @Override
        protected void onPostExecute(List<YourDataClass> dataList) {
            // This is called on the UI thread when doInBackground() returns, with
            // the result as the parameter
        }
    }.execute();

答案 1 :(得分:0)

所有UI组件都只能通过Main线程访问,因为UI元素不是安全线程,并且main线程是它的所有者。

mHandler = new Handler(Looper.getMainLooper()) {
    @Override
    public void handleMessage(Message inputMessage) {

     //Call your UI related method

    }
}

参考:https://developer.android.com/training/multiple-threads/communicate-ui#java

答案 2 :(得分:0)

您只能通过UI / Main线程与UI元素进行交互。

以下代码应将您的操作发布到UI线程上:

keys