【问题标题】:recyclerView.adapter on notifydatasetchanged hangs the ui android [duplicate]notifydatasetchanged 上的 recyclerView.adapter 挂起 ui android [重复]
【发布时间】:2017-03-28 13:10:55
【问题描述】:

我在更新我的 recyclerview 时遇到了问题,通知数据集已更改,因为它会在调用时将 ui 挂起几秒钟。 网上搜索后,建议在后台线程更新适配器。

 private synchronized void updateAdapter() {
    AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() {
        @Override
        public Void doInBackground(Void... params) {
            adapter.notifyDataSetChanged();
            return null;
        }
    };
    task.execute();
}

在运行这行代码时,应用程序因错误而崩溃,

“只有创建视图层次结构的原始线程才能接触其视图。”

进一步搜索,建议解决方案是在ui线程上运行。

runOnUiThread(new Runnable() {
 @Override
 public void run() {

}
});

这让我回到了最初的问题。 我应该如何处理这个问题?任何帮助表示赞赏。 谢谢。

【问题讨论】:

  • 您不能在doInBackground 中执行notifyDataSetChanged,您必须在onProgressUpdateonPostExecute . cause doInBackground 中执行此操作,这只是在工作线程中触发的回调,并且您想做notifyDataSetChanged 必须在 UI 线程中,因此您可以在 onProgressUpdate 中执行 notifyDataSetChanged ,它作为处理程序将您的按摩从工作线程转移到 UI 线程,或者在工作线程之后在您的 UI 线程中调用的`onPostExecute完成它的工作。
  • 但这会挂起 ui。这是最初的问题。
  • 这只是证明人们甚至没有阅读就将问题标记为重复,这对社区来说非常重要。

标签: android multithreading android-asynctask android-recyclerview notifydatasetchanged


【解决方案1】:
 private synchronized void updateAdapter() {
    AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() {
        @Override
        public Void doInBackground(Void... params) {
            adapter.notifyDataSetChanged();
            return null;
        }
    };
    task.execute();
}

请研究 Asynctask doInBackground 不应该有任何 UI 更改。在这种情况下,您正在 asynctask 中的单独线程上执行 UI 更改。将您的 notifydatasetchanged 放在 onPostExecute 上,如下所示(适用于 Main Thread )。添加 onPreExcute()onPostExecute() 在 Main UI 上执行,onBackground() 在单独的线程(不是 Main UI)上执行。

 private synchronized void updateAdapter() {
    AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() {
        @Override
        public Void doInBackground(Void... params) {
           // query your db or perform long operations here 
           return null;
        }

        @Override
        onPostExecute(Void.. params){
             adapter.notifyDataSetChanged();
        }
    };
    task.execute();
}

【讨论】:

  • onPostExeceute 在 UI 线程中运行,它也会挂起 UI
  • onRunning onPostExecute 它会挂起 ui,这是最初的问题。
  • 使用 notifychanged( int position ) 这将帮助您只更新特定的单元格。请分享您的代码,因为除非您使用大量不同的视图,否则不应该太滞后
  • 我遇到了您所面临的同样问题。你找到解决方案了吗?
  • 嗨@ShockWave...请分享代码... AsyncTask 应该足以解决问题...
猜你喜欢
  • 1970-01-01
  • 2021-06-06
  • 1970-01-01
  • 1970-01-01
  • 2016-05-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多