【问题标题】:UI blocks when refreshing a listview (how to solve?)刷新列表视图时 UI 阻塞(如何解决?)
【发布时间】:2014-08-29 20:06:39
【问题描述】:

我有一个按钮。点击后,我正在刷新一个列表。

我正在经历的事情

state_pressed 颜色会停留很长时间(意味着 UI 线程被阻塞)
(注意:按钮背景定义如在 state_pressed="true" 上颜色变化)

问题

如何在不阻塞 UI 的情况下单击按钮刷新列表?

我的代码

mButton.setOnClickListener(new View.OnClickListener() {
    public void onClick(View v) {
        refreshListView(data);
    }
});

public void refreshListView(ArrayList data) {
    // I am setting setNotifyOnChange() to false
    // to prevent notifyDataSetChanged() to be triggered twice, by clear() and by addAll()
    mArrayAdapter.setNotifyOnChange(false)
    mArrayAdapter.clear();
    mArrayAdapter.addAll(data);
    // I am triggering notifyDataSetChanged() explicitely
    mArrayAdapter.notifyDataSetChanged();
    mListView.post(new Runnable() {
        @Override
        public void run() {
            // this is to reset to the top of the list, after the list has been populated
            mListView.setSelectionAfterHeaderView();
        }
    });
}

编辑

我想我通过从 View.post() 调用刷新代码解决了这个问题,但我想知道这是否应该总是需要:

mButton.setOnClickListener(new View.OnClickListener() {
    public void onClick(View v) {
        mListView.post(new Runnable() {
            @Override
            public void run() {
                refreshListView(data);
            }
        });
    }
});

【问题讨论】:

  • 看你的代码,我不认为问题区域在上面的代码中... mArrayAdapter 是标准适配器还是自定义的?如果是定制的,是否有一些可能需要更长时间的数据处理?过去我遇到过这个问题,我的适配器要从服务器抓取图像并显示...我必须把它放在 AsyncTask 上...
  • @AtulDravid-WhitePvt.Ltd.,它是一个自定义适配器,但它使用已处理的数据。我刚刚意识到我可以通过在View.post() 中调用refreshListView() 来解决问题。这是一个好的解决方案吗?

标签: android listview android-arrayadapter ui-thread


【解决方案1】:

您的 refreshList 应该在 ui 线程上运行...并且 new Runnable 应该与线程一起使用...如果您没有创建新线程,您将使用 Runnable 作为一种匿名类... android 这不是一个好习惯...但是,如果这解决了您的问题,从技术上讲,您的代码没有任何问题...

【讨论】:

  • 据我了解,View.post() 也是一种从 UI 线程内推迟 UI 线程操作(到当前 UI 线程队列的末尾)的方法。在这种情况下,我将列表视图的刷新推迟到按钮单击操作结束时。通过这种方式,按钮不会卡在 state_pressed 上,因为 UI 线程似乎被列表刷新操作阻塞。虽然我确实觉得很奇怪 listview 应该明显地阻塞 UI 线程。
  • 我从来没有用过 View.post... 你能试着不只用它吗?我猜 view.post 可能会导致 Ui 线程出现某种瓶颈......
  • 我认为view.post() 只是推迟了 UI 操作。它不应该造成瓶颈。例如,在refreshListView() 函数中,我使用它将列表重置为顶部,在列表被填充后。我不知道如何以另一种方式实现同​​样的目标。
  • 嗯...您是否尝试过您建议的选项?那给了你结果吗?如果是,我不认为你在这方面做错了什么。只是 Runnable 的用法有点不同...
  • 你也可以使用 Handler 来做这个... Handler 可以让你通过发送消息来执行处理... 我更经常使用 Handlers 和 Threads 作为组合...
猜你喜欢
  • 2020-09-09
  • 1970-01-01
  • 2016-07-31
  • 2014-04-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-18
相关资源
最近更新 更多