Обновление RecyclerView из другого потока, вызывающее ошибку - PullRequest
0 голосов
/ 23 октября 2018

У меня есть список элементов, который был обновлен в другом действии, и когда я возвращаюсь из занятия, я хочу обновить свое представление о переработчике с помощью совершенно нового ArrayList ().Чтобы избежать отставания, я помещаю это обновление в другой поток 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 голосов
/ 23 октября 2018

Вы можете взаимодействовать с элементами пользовательского интерфейса только из пользовательского интерфейса / основного потока.

Приведенный ниже код должен опубликовать вашу операцию в потоке пользовательского интерфейса:

fun adapterRefreshFoods(filteredList: ArrayList<Food>){
    if (!filteredList.isEmpty()){
        foodList = filteredList
        Handler(Looper.getMainLooper()).post { 
            // Code here will run in UI thread
            notifyDataSetChanged()
        }
    }
}
0 голосов
/ 23 октября 2018

Вы никогда не должны обращаться к элементам пользовательского интерфейса из потоков, отличных от основного потока / потока пользовательского интерфейса.Вы можете использовать AsyncTask для загрузки данных в фоновом режиме и постоянного обновления пользовательского интерфейса, используя publishProgress() и onProgressUpdate().

    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();
0 голосов
/ 23 октября 2018

Доступ ко всем компонентам пользовательского интерфейса возможен только через главный поток, поскольку элементы пользовательского интерфейса не являются поточно-ориентированными, и основной поток является его владельцем.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...