【问题标题】:NullPointerException on dynamic AutoCompleteTextView动态 AutoCompleteTextView 上的 NullPointerException
【发布时间】:2012-10-07 14:11:06
【问题描述】:

部分用户报告此错误:

java.lang.NullPointerException
at android.widget.ArrayAdapter.getCount(ArrayAdapter.java:291)
at android.widget.AutoCompleteTextView$PopupDataSetObserver$1.run(AutoCompleteTextView.java:1670)
at android.os.Handler.handleCallback(Handler.java:587)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:123)
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)

这是我的代码 sn-p:

    private List<City> autoCompleteCities = new ArrayList<City>();
    private List<City> autoCompleteCitiesOld = new ArrayList<City>();
    private ArrayAdapter<String> autoCompleteAdapter;
    private AutoCompleteTextView cityView;

    ...

    autoCompleteAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line);
    autoCompleteAdapter.setNotifyOnChange(true);

    cityView = (AutoCompleteTextView) findViewById(R.id.city);      

    cityView.setAdapter(autoCompleteAdapter);
    cityView.addTextChangedListener(new TextWatcher() {

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            LogUtil.i("!!!!!!!!!!!!! ontextchanged", s.toString());
            autoCompleteAdapter.clear();
            autoCompleteCitiesOld = autoCompleteCities;
            if (s.toString().length() > 2) {
                autoCompleteCities = search(s.toString());
                for (City city : autoCompleteCities) {
                    autoCompleteAdapter.add(city.getDisplayName());
                }
            }
        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        }

        @Override
        public void afterTextChanged(Editable s) {
        }
    });

这不会发生在我身上,但我有足够的错误报告知道它发生在几个用户身上。知道有什么问题吗?为什么只有少数用户会发生这种情况?

我发现了这个post,但是将新的自动完成值的获取放在 AsyncTask 中意味着结果总是比用户输入的内容晚一个字符。

【问题讨论】:

  • 如果支持适配器的列表数据在某个时刻变为空,则会发生该异常。当适配器第一次初始化时(即使它只使用代码中的布局文件完成),一个空列表被分配,所以你必须稍后做一些事情,使列表null(如果你只使用@ 987654325@ 不应该发生的方法)。此外,您对AutoCompleteTextView(修改适配器的方式)的使用也不是正确的方式。
  • 正确的方法是什么?除了上面代码中显示的内容之外,我没有对 autoCompleteAdapter 的引用...
  • 正确的方法是通过在适配器中实现自己的过滤器来自动完成(因为AutocompleteTextView 正在使用过滤器来获取建议)。如果值(或城市)的完整列表在搜索之间没有修改,那么每次用户修改 AutoCompleteTextView 中的文本时重新设置适配器的数据是没有意义的。
  • 如果我一次将所有城市添加到适配器然后过滤它们,因为有大约 100,000 个城市,所以需要很长时间。这就是为什么它需要动态更新...
  • 我不是说要一次添加所有城市(因为 AutoCompleteTextview 只有在您插入字符时才会显示建议(这实际上调用了适配器的 getFilter 方法)) ,您只需要移动您当前在自定义适配器的Filter 实现中所做的事情(您还可以获得一个后台线程,因此没有任何问题)。

标签: android autocompletetextview


【解决方案1】:

您在哪里将 ArrayList 传递给 ArrayAdapter。 NullPointerException 在计算 ArrayAdapter 中的列表长度时抛出。但是列表并没有传递给Adapter,所以默认Adapter中的列表对象包含null。

【讨论】:

  • 我实际上没有ArrayList,而是直接将城市名称添加到适配器中。你是说我需要添加这样的东西: ArrayList city = new ArrayList(); autoCompleteAdapter = new ArrayAdapter(this, android.R.layout.simple_dropdown_item_1line, city);
【解决方案2】:

我的假设是您在某处使用静态变量,这些变量在活动重新创建后被清​​空。 在这里查看我的答案:Public static variables and Android activity life cycle management

创建 android v.4 模拟器,进入开发者设置,禁用后台任务,禁用多个活动,然后尝试使用您的应用程序 - 很可能会失败。

【讨论】:

    【解决方案3】:

    你在哪里添加了 String 的数组,错误的原因可能是空数组列表 作为: autoCompleteAdapter = new ArrayAdapter(this, android.R.layout.simple_dropdown_item_1line);

    这里你没有分配任何字符串数组

    并输入您的完整代码,这将有助于人们理解问题

    【讨论】:

      【解决方案4】:

      最好在使用下面的对象之前进行空检查,并在搜索功能中也这样做..

       if (s.toString().length() > 2) {
           autoCompleteCities = search(s.toString());
           if(autoCompeleteCities!=null){     
               for (City city : autoCompleteCities) {
                    autoCompleteAdapter.add(city.getDisplayName());
               }
             }
      

      【讨论】:

        【解决方案5】:

        我在同一个问题上遇到了完全相同的问题。就我而言,我有数千条街道,我可以从列表中动态添加和删除。 在我的情况下,当我在 AutoComplete 字段中输入一些值时,它总是可重现的,比如 3 个字符(阈值设置为 0),因此出现下拉列表,然后我通过删除按钮非常快速地删除这些字符。这意味着我多次点击删除按钮。那时它总是崩溃。我发现 clear 会导致崩溃。我在 beforeTextChanged 中清除了并且崩溃消失了:

        public class StreetTextWatcher implements TextWatcher {
        
            private final StreetArrayAdapter adapter;
            private boolean alreadyAdded = false;
        
            public StreetTextWatcher(StreetArrayAdapter adapter) {
                this.adapter = adapter;
            }
        
            @Override
            public void afterTextChanged(Editable s) {
                //not used
            }
        
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                if (s.length() < 1)  {
                    adapter.clear();
        
                    alreadyAdded = false;
                }
            }
        
            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {           
                if (s.length() == 1) {
                    if (s.toString().toLowerCase(Locale.GERMAN).startsWith("a") && !alreadyAdded)  {
                        adapter.addAll(StreetNames.STREETS_A);
                        alreadyAdded = true;
                    }
        
                    if (s.toString().toLowerCase(Locale.GERMAN).startsWith("b") && !alreadyAdded)  {
                        adapter.addAll(StreetNames.STREETS_B);
                        alreadyAdded = true;
                    }
        
                    //more streets...
                }
            }
        }
        

        StreetArrayAdapter:

        public class StreetArrayAdapter extends ArrayAdapter<String> {
        
            public StreetArrayAdapter(Context context, int textViewResourceId) {
                super(context, textViewResourceId);
            }
        
            public void addAll(String[] streets) {
                for (String street : streets) {
                    add(street);
                }
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-10-12
          • 1970-01-01
          • 1970-01-01
          • 2011-05-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-12-26
          相关资源
          最近更新 更多