草庐IT

Android AutoCompleteTextView 在快速删除文本时崩溃

coder 2023-12-09 原文

我有一个关键字列表(大约 1000 个单词),我将其设置为一个 ArrayAdapter 以供 AutoCompleteTextView 处理。基本过程工作正常。当我选择一个长单词(上面 10 个字符)时出现问题,然后使用键盘退格按钮删除单词(按住按钮),在删除大约 5 个字符后应用程序崩溃并出现以下错误。

01-16 13:27:23.082: ERROR/AndroidRuntime(2874): FATAL EXCEPTION: main
        java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread. [in ListView(-1, class android.widget.AutoCompleteTextView$DropDownListView) with Adapter(class com.hdm_i.dm.corp.android.muenchen.adapters.PoiAutoCompleteAdapter)]
        at android.widget.ListView.layoutChildren(ListView.java:1527)
        at android.widget.AbsListView.onLayout(AbsListView.java:1430)
        at android.view.View.layout(View.java:7228)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:338)
        at android.view.View.layout(View.java:7228)
        at android.view.ViewRoot.performTraversals(ViewRoot.java:1145)
        at android.view.ViewRoot.handleMessage(ViewRoot.java:1865)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:130)
        at android.app.ActivityThread.main(ActivityThread.java:3687)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:507)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:842)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
        at dalvik.system.NativeStart.main(Native Method)  

下面是我的代码,我做错了什么吗?预先感谢您的建议:-)

public class PoiAutoCompleteAdapter extends ArrayAdapter<SearchTextAutoSuggest> implements Filterable {

    private List<SearchTextAutoSuggest> searchTextAutoSuggestList = new ArrayList<SearchTextAutoSuggest>();
    private SearchTextAutoSuggest defaultSuggestion = new SearchTextAutoSuggest();

    private Handler uiThreadHandler;

    public PoiAutoCompleteAdapter(Context context, int viewResourceId, Handler uiThreadHandler) {
        super(context, viewResourceId);
        this.uiThreadHandler = uiThreadHandler;
        defaultSuggestion.setName(AppConstants.DEFAULT_SEARCH_STRING_NAME);
    }

    @Override
    public int getCount() {
        return searchTextAutoSuggestList.size();
    }

    @Override
    public SearchTextAutoSuggest getItem(int position) {
        return searchTextAutoSuggestList.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public Filter getFilter() {
        Filter filter = new Filter() {

            @Override
            protected FilterResults performFiltering(CharSequence constraint) {
                FilterResults filterResults = new FilterResults();
                synchronized (filterResults) {
                    if (constraint != null) {
                        // Clear and Retrieve the autocomplete results.
                        searchTextAutoSuggestList.clear();
                        searchTextAutoSuggestList = getFilteredResults(constraint);

                        // Assign the data to the FilterResults
                        filterResults.values = searchTextAutoSuggestList;
                        filterResults.count = searchTextAutoSuggestList.size();
                    }

                    return filterResults;
                }
            }

            @Override
            protected void publishResults(CharSequence constraint, final FilterResults filterResults) {
                uiThreadHandler.post(new Runnable() {
                    public void run() {
                        synchronized (filterResults) {
                            if (filterResults != null && filterResults.count > 0) {
                                notifyDataSetChanged();
                            } else {
                                Logs.e("Tried to invalidate");
                                notifyDataSetInvalidated();
                            }
                        }
                    }
                });
            }
        };
        return filter;
    }

    private List<SearchTextAutoSuggest> getFilteredResults(CharSequence constraint) {
        List<SearchTextAutoSuggest> searchTextAutoSuggestList = AppContext.searchTextAutoSuggestList;
        List<SearchTextAutoSuggest> filteredSearchTextAutoSuggestList = new ArrayList<SearchTextAutoSuggest>();

        // Assign constraint as a default option into the list
        defaultSuggestion.setLabel(getContext().getString(R.string.general_default_search_str) + " \'" + constraint + "\'");
        filteredSearchTextAutoSuggestList.add(defaultSuggestion);

        for (int i = 0; i < searchTextAutoSuggestList.size(); i++) {
            if (searchTextAutoSuggestList.get(i).getLabel().toLowerCase().startsWith(constraint.toString().toLowerCase())) {
                filteredSearchTextAutoSuggestList.add(searchTextAutoSuggestList.get(i));
            }
        }

        return filteredSearchTextAutoSuggestList;
    }

}

最佳答案

因为 performFiltering 在工作线程中执行。您在此线程中分配 searchTextAutoSuggestList 变量,但您必须仅在 UI 线程中更改适配器的数据。此外,publishResults 方法在 UI 线程中执行,因此您在这里不需要任何处理程序。

@Override
protected FilterResults performFiltering(CharSequence constraint) {
    FilterResults filterResults = new FilterResults();
    synchronized (filterResults) {
        if (constraint != null) {
            // Clear and Retrieve the autocomplete results.
            List<SearchTextAutoSuggest> resultList = getFilteredResults(constraint);

            // Assign the data to the FilterResults
            filterResults.values = resultList;
            filterResults.count = resultList.size();
        }
        return filterResults;
    }
}

@Override
protected void publishResults(CharSequence constraint, final FilterResults filterResults) {
    if (filterResults != null && filterResults.count > 0) {
        searchTextAutoSuggestList.clear();
        searchTextAutoSuggestList = filterResults.values;
        notifyDataSetChanged();
    } else {
        Logs.e("Tried to invalidate");
        notifyDataSetInvalidated();
    }

}

关于Android AutoCompleteTextView 在快速删除文本时崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21162170/

有关Android AutoCompleteTextView 在快速删除文本时崩溃的更多相关文章

  1. ruby - 使用 ruby​​ 将 HTML 转换为纯文本并维护结构/格式 - 2

    我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h

  2. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

  3. ruby - 我可以使用 Ruby 从 CSV 中删除列吗? - 2

    查看Ruby的CSV库的文档,我非常确定这是可能且简单的。我只需要使用Ruby删除CSV文件的前三列,但我没有成功运行它。 最佳答案 csv_table=CSV.read(file_path_in,:headers=>true)csv_table.delete("header_name")csv_table.to_csv#=>ThenewCSVinstringformat检查CSV::Table文档:http://ruby-doc.org/stdlib-1.9.2/libdoc/csv/rdoc/CSV/Table.html

  4. ruby - 检查 "command"的输出应该包含 NilClass 的意外崩溃 - 2

    为了将Cucumber用于命令行脚本,我按照提供的说明安装了arubagem。它在我的Gemfile中,我可以验证是否安装了正确的版本并且我已经包含了require'aruba/cucumber'在'features/env.rb'中为了确保它能正常工作,我写了以下场景:@announceScenario:Testingcucumber/arubaGivenablankslateThentheoutputfrom"ls-la"shouldcontain"drw"假设事情应该失败。它确实失败了,但失败的原因是错误的:@announceScenario:Testingcucumber/ar

  5. Ruby Readline 在向上箭头上使控制台崩溃 - 2

    当我在Rails控制台中按向上或向左箭头时,出现此错误:irb(main):001:0>/Users/me/.rvm/gems/ruby-2.0.0-p247/gems/rb-readline-0.4.2/lib/rbreadline.rb:4269:in`blockin_rl_dispatch_subseq':invalidbytesequenceinUTF-8(ArgumentError)我使用rvm来管理我的ruby​​安装。我正在使用=>ruby-2.0.0-p247[x86_64]我使用bundle来管理我的gem,并且我有rb-readline(0.4.2)(人们推荐的最少

  6. ruby - 我可以使用 aws-sdk-ruby 在 AWS S3 上使用事务性文件删除/上传吗? - 2

    我发现ActiveRecord::Base.transaction在复杂方法中非常有效。我想知道是否可以在如下事务中从AWSS3上传/删除文件:S3Object.transactiondo#writeintofiles#raiseanexceptionend引发异常后,每个操作都应在S3上回滚。S3Object这可能吗?? 最佳答案 虽然S3API具有批量删除功能,但它不支持事务,因为每个删除操作都可以独立于其他操作成功/失败。该API不提供任何批量上传功能(通过PUT或POST),因此每个上传操作都是通过一个独立的API调用完成的

  7. ruby - 如何安全地删除文件? - 2

    在Ruby中是否有Gem或安全删除文件的方法?我想避免系统上可能不存在的外部程序。“安全删除”指的是覆盖文件内容。 最佳答案 如果您使用的是*nix,一个很好的方法是使用exec/open3/open4调用shred:`shred-fxuz#{filename}`http://www.gnu.org/s/coreutils/manual/html_node/shred-invocation.html检查这个类似的帖子:Writingafileshredderinpythonorruby?

  8. ruby-on-rails - 标准化文件名的字符串,删除重音和特殊字符 - 2

    我正在尝试找到一种方法来规范化字符串以将其作为文件名传递。到目前为止我有这个:my_string.mb_chars.normalize(:kd).gsub(/[^\x00-\x7F]/n,'').downcase.gsub(/[^a-z]/,'_')但第一个问题:-字符。我猜这个方法还有更多问题。我不控制名称,名称字符串可以有重音符、空格和特殊字符。我想删除所有这些,用相应的字母('é'=>'e')替换重音符号,并将其余的替换为'_'字符。名字是这样的:“Prélèvements-常规”“健康证”...我希望它们像一个没有空格/特殊字符的文件名:“prelevements_routin

  9. ruby-on-rails - 为什么在 Rails 5.1.1 中删除了 session 存储初始化程序 - 2

    我去了这个website查看Rails5.0.0和Rails5.1.1之间的区别为什么5.1.1不再包含:config/initializers/session_store.rb?谢谢 最佳答案 这是删除它的提交:Setupdefaultsessionstoreinternally,nolongerthroughanapplicationinitializer总而言之,新应用没有该初始化器,session存储默认设置为cookie存储。即与在该初始值设定项的生成版本中指定的值相同。 关于

  10. ruby - 如果它是标点符号,我怎么能从字符串中删除最后一个字符,在 ruby​​ 中? - 2

    啊,正则表达式有点困惑。我正在尝试删除字符串末尾所有可能的标点符号:ifstr[str.length-1]=='?'||str[str.length-1]=='.'||str[str.length-1]=='!'orstr[str.length-1]==','||str[str.length-1]==';'str.chomp!end我相信有更好的方法来做到这一点。有什么指点吗? 最佳答案 str.sub!(/[?.!,;]?$/,'')[?.!,;]-字符类。匹配这5个字符中的任何一个(注意,。在字符类中并不特殊)?-前一个字符或组

随机推荐