AutoCompleteTextView随机抛出IllegalStateException

时间:2013-12-07 15:44:33

标签: java android android-asynctask autocompletetextview illegalstateexception

由于我的AutoCompleteTextView中的IllegalStateException,我收到了一些关于我的Android应用程序崩溃的Play商店报告。但是,我自己从未能够重新创建这个问题。 AutoCompleteTextView使用自定义过滤,我或多或少遵循以下代码:Custom filtering in AutoCompleteTextView not working

我已经对这个问题做了一些研究,发现这是结果之一:How to resolve "The content of the adapter has changed but ListView did not receive a notification” exception但仍然无法解决我的代码有什么问题。我甚至无法弄清楚导致异常发生的原因,它只是随机发生,尽管大部分时间都没有发生。更令人沮丧的是,异常堆栈跟踪没有指出导致异常的代码行。

以下是异常堆栈跟踪:

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 transponders.transmob.JourneyPlanner$LocationAdapter)]
at android.widget.ListView.layoutChildren(ListView.java:1541)
at android.widget.AbsListView.onLayout(AbsListView.java:1428)
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:1148)
at android.view.ViewRoot.handleMessage(ViewRoot.java:1868)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3691)
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:907)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:665)
at dalvik.system.NativeStart.main(Native Method)

这是自定义适配器类中的自定义过滤器代码:

        @Override
        public Filter getFilter() 
        {
            Filter filter = new Filter(){
                  @Override
                  protected FilterResults performFiltering(CharSequence constraint)
                  {
                      locations.clear();
                      FilterResults results = new FilterResults();
                      String typedText = ownerACTV.getText().toString();

                      try
                      {
                          Log.d("performFiltering", "TYPED TEXT LENGTH: " + typedText.length());
                          if(!typedText.equals("Current location"))
                          {
                              String url = "some URL";
                              request = new JSONRequest();
                              request.setListener(JourneyPlanner.this);
                              request.execute(url);

                              String result = request.get();

                              Object obj = JSONValue.parse(result);
                              JSONArray array = (JSONArray)((JSONObject)obj).get("Locations");

                              for(int i = 0; i < array.size(); i++)
                              {
                                  JSONObject location = (JSONObject) array.get(i);
                                  String desc = (String) location.get("Description");
                                  String id = (String) location.get("Id");

                                  Log.d("filterResults", "Description: " + desc);
                                  Log.d("filterResults", "ID: " + id);

                                  String[] splitted = desc.split(" \\(");
                                  if (splitted.length > 1)
                                      desc = splitted[0];

                                  locationsToID.put(desc, id);
                                  locations.add(desc);
                              }
                          }

                          results.values = locations;
                          results.count = locations.size();

                      }
                      catch (Exception e)
                      {
                          e.printStackTrace();
                      }

                      Log.d("performFiltering", "return FilterResults");
                      return results;
                  }

                  @Override
                  protected void publishResults(CharSequence arg0, FilterResults results) 
                  {  
                      if (results != null && results.count > 0)
                      {
                         notifyDataSetChanged();
                      }
                      else
                      {
                          notifyDataSetInvalidated();
                      }
                  }
            };

            return filter;
        }

如有必要,我也可以给你代码的其他部分。 我必须打电话给网络以填充自动完成下拉列表,我猜它可能是导致异常的那个?

感谢任何帮助,提前谢谢!

2 个答案:

答案 0 :(得分:1)

问题是您在非ui线程中修改的“位置”字段(perfornFiltering方法),您应该使用传递给publishResults的FilterResults

答案 1 :(得分:1)

这是getFilter方法:工作正常

 @Override
 public Filter getFilter() {
 Filter filter = new Filter() {
    @Override
    protected FilterResults performFiltering(final CharSequence  constraint) {
        final FilterResults filterResults = new FilterResults();

       activity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                resultList = autocomplete(constraint.toString());

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

            }
        });




        return filterResults;
    }

    @Override
    protected void publishResults(CharSequence constraint, final     FilterResults results) {
        try {
           activity.runOnUiThread(new Runnable() {
               @Override
               public void run() {
                   if (results != null && results.count > 0) {

                      // resultList=(ArrayList<String>)results.values;
                       notifyDataSetChanged();
                   } else {
                       notifyDataSetInvalidated();