java - ArrayAdapter - 如何停止 getView 调用?

标签 java android listview android-arrayadapter indexoutofboundsexception

如何停止 getView 调用,直到再次调用 notificationDatasetChanged()?

我的问题:

我有一个文本字段,用于过滤文本更改上的适配器。如果我太频繁地更改文本,我会收到 ArrayIndexOutOfBoundsException,因为当辅助过滤操作已经在运行时,getView 当然仍在访问适配器列表。

ATM 的流程是这样的:

  1. 后台过滤+notifyDatasetChanged
  2. 多次调用 GetView
  3. 在处理下一个过滤器时,由于第一个过滤器的原因,GetView 仍在后台被调用。但是 GetView 由于列表访问而出现异常(过滤操作更改列表)。所以我想停止 GetView 调用,然后启动任何给定的过滤器操作。

编辑:

如果我看到过滤器线程处于 Activity 状态,我正在考虑立即从 getview 返回吗?

编辑:

确定相关适配器代码:

@Override
    protected FilterResults performFiltering(CharSequence constraint) {
      filterLock.acquireUninterruptibly();

      FilterResults r = new FilterResults();
      List<T> items = null;
      m_Filter = constraint;

      if (constraint == null /* TextUtils.isEmpty(constraint) */) { // AR
        // auskommentiert
        // da
        // ungewünscht
        items = m_AllItems;
      } else {
        items = m_FilteredItems;
        items.clear();

        synchronized (SyncLock) {
          for (T item : m_AllItems) {
            if (DynamicArrayAdapter.this.filter(item, constraint)) {
              items.add(item);
            }
          }
        }
      }

      r.values = items;
      r.count = items.size();

      return r;
    }

    @SuppressWarnings("unchecked")
    @Override
    protected void publishResults(CharSequence constraint, FilterResults results) {

      m_Items = (List<T>) results.values;

      notifyDataSetChanged();

      filterLock.release();
    }

这是从 Filter 扩展而来的过滤器。 m_Items 和 m_AllItems 在适配器中使用(第一个包含已过滤的内容,第二个包含未过滤的内容)。正如您所看到的,它们在performFiltering() 中没有被修改。另外,filterLock 是一个大小为 1 的信号量,因此不会同时发生 2 个过滤操作。

编辑2:

另外,在我的 onTextChanged 中,我可以向您保证,我不会以任何方式修改适配器,也不会在从 PerformFiltering() 调用的 filter() 方法中修改适配器

最佳答案

不是从 UI 线程对适配器进行更改才是导致问题的原因。 如果您将所有适配器修改发布到 UI 线程,则不会发生这种情况,因为这一切都会一个接一个地发生。

您可以在不同的线程中执行繁重的处理,但是当您想要将更改放入适配器中时,您需要使用处理程序或 Activity.runOnUiThread 在 UI 线程上执行此操作。 。例如:

// Really heavy filtering process

runOnUiThread(new Runnable(){
          public void run(){
               // Change items of Adapter here
               // Now we are notifying that the data has changed.
               mAdapter.notifyDataSetChanged();
          }
    });

看到你的代码后: 正如 Luksprog 所说,您不应该直接从其他线程更改列表,而应使用列表的副本。 发生的情况是 ListView 接受大小为 X 的列表,但您已经将其更改为 Y 大小,而 ListView 并不知道这一点。 您需要对项目列表的副本进行操作,完成后,将一个 Runnable 发布到 UI 线程,该 Runnable 会更改适配器中的项目列表并调用 notifyDataSetChanged() ,这样您就不会与 ListView 和 Adapter 发生冲突。

关于java - ArrayAdapter - 如何停止 getView 调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15646482/

相关文章:

java - 在 shell 脚本中调用连续的 java 任务

android - 我想使布局边框如下图所示

android - 用于 Android 听写应用程序的 PocketSphinx

android - 在 Listview 中更改 TextView 文本未得到反射(reflect)

java - 我正在尝试 Spring MVC,当我在 Controller 类中添加 @Autowired 时,出现以下错误 :

java - 使用 HashMap 计算文档频率 [Java]

java - 等待 lambda 完成的正确方法

Android assemble build 搞砸了 GUI

android - 如何使 ListView 增长而不是滚动?

android:在 ListView 行内单击按钮播放音频