【问题标题】:IllegalStateException while search from Edittext从 Edittext 搜索时出现 IllegalStateException
【发布时间】:2014-08-26 22:34:17
【问题描述】:

我正在使用TextWatcher 过滤我的列表视图的结果。但我得到以下错误:

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. with Adapter

我没有在任何地方使用过后台线程。如何摆脱这个???

    @Override
    public Filter getFilter() {
        // TODO Auto-generated method stub

        Filter filter = new Filter() {

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

                contactNameList = (ArrayList<String>) results.values;
                //Log.e("RESULT:",results.values.toString() );
                //                    getActivity().runOnUiThread(new Runnable() {
                //                        public void run() {
                try {
                    if (results.count > 0) {
                        mContactListAdapter.notifyDataSetChanged();
                    } else {
                        mContactListAdapter.notifyDataSetInvalidated();
                    }  

                } catch (Exception e) {
                    // TODO: handle exception
                    e.printStackTrace();
                }
            }

            @Override
            protected synchronized FilterResults performFiltering(CharSequence constraint) {

                FilterResults results = new FilterResults();        // Holds the results of a filtering operation in values
                ArrayList<String> FilteredArrList = new ArrayList<String>();

                // set the Filtered result to return
                try {
                    String sql = "SELECT * FROM "
                            +MySQLiteHelper.TABLE_NAME_CONTACT
                            +" WHERE "
                            +MySQLiteHelper.COLUMN_CNT_NICK_NAME
                            +" LIKE '"+constraint.toString()+"%'"
                            +" ORDER BY "
                            +(prefs.getOrderBy().equalsIgnoreCase("")? MySQLiteHelper.COLUMN_CNT_NICK_NAME: prefs.getOrderBy()) 
                            +" COLLATE NOCASE;";                                      

                    Log.e("FILTER SQL ",sql);
                    synchronized (this) {
                        fetchContactData(sql);            
                    }


                    results.count = contactNameList.size();
                    results.values = contactNameList;
                    return results;

                } catch (Exception e) {
                    // TODO: handle exception
                    e.printStackTrace();
                }
                return null;                
            }
        };
        return filter;            
    }

编辑 - 整个 logcat:

E/onQueryTextChange(17748): contact onTextChanged:p 08-22 19:18:10.035: E/FILTER SQL(17748): SELECT * FROM contacts WHERE cnt_nick LIKE 'p%' ORDER BY cnt_nick COLLATE NOCASE; 08-22 19:18:10.047: D/AndroidRuntime(17748): Shutting down VM 08-22 19:18:10.048: W/dalvikvm(17748): threadid=1: thread exiting with uncaught exception (group=0x418aa9a8) 08-22 19:18:10.060: E/AndroidRuntime(17748): FATAL EXCEPTION: main 08-22 19:18:10.060: E/AndroidRuntime(17748): 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(2131492994, class android.widget.ListView) with Adapter(class com.ecosmob.contactpro.contacts.ContactFragment$ContactListAdapter)] 08-22 19:18:10.060: E/AndroidRuntime(17748): at android.widget.ListView.layoutChildren(ListView.java:1559) 08-22 19:18:10.060: E/AndroidRuntime(17748): at android.widget.AbsListView.onLayout(AbsListView.java:2052) 08-22 19:18:10.060: E/AndroidRuntime(17748): at android.view.View.layout(View.java:14118) 08-22 19:18:10.060: E/AndroidRuntime(17748): at android.view.ViewGroup.layout(ViewGroup.java:4467) 08-22 19:18:10.060: E/AndroidRuntime(17748): at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1021) 08-22 19:18:10.060: E/AndroidRuntime(17748): at android.view.View.layout(View.java:14118) 08-22 19:18:10.060: E/AndroidRuntime(17748): at android.view.ViewGroup.layout(ViewGroup.java:4467) 08-22 19:18:10.060: E/AndroidRuntime(17748): at android.widget.FrameLayout.onLayout(FrameLayout.java:448) 08-22 19:18:10.060: E/AndroidRuntime(17748): at android.view.View.layout(View.java:14118) 08-22 19:18:10.060: E/AndroidRuntime(17748): at android.view.ViewGroup.layout(ViewGroup.java:4467) 08-22 19:18:10.060: E/AndroidRuntime(17748): at android.support.v4.view.ViewPager.onLayout(ViewPager.java:1589) 08-22 19:18:10.060: E/AndroidRuntime(17748): at android.view.View.layout(View.java:14118) 08-22 19:18:10.060: E/AndroidRuntime(17748): at android.view.ViewGroup.layout(ViewGroup.java:4467) 08-22 19:18:10.060: E/AndroidRuntime(17748): at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1670) 08-22 19:18:10.060: E/AndroidRuntime(17748): at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1528) 08-22 19:18:10.060: E/AndroidRuntime(17748): at android.widget.LinearLayout.onLayout(LinearLayout.java:1441) 08-22 19:18:10.060: E/AndroidRuntime(17748): at android.view.View.layout(View.java:14118) 08-22 19:18:10.060: E/AndroidRuntime(17748): at android.view.ViewGroup.layout(ViewGroup.java:4467) 08-22 19:18:10.060: E/AndroidRuntime(17748): at android.widget.FrameLayout.onLayout(FrameLayout.java:448) 08-22 19:18:10.060: E/AndroidRuntime(17748): at android.view.View.layout(View.java:14118) 08-22 19:18:10.060: E/AndroidRuntime(17748): at android.view.ViewGroup.layout(ViewGroup.java:4467) 08-22 19:18:10.060: E/AndroidRuntime(17748): at android.support.v4.widget.DrawerLayout.onLayout(DrawerLayout.java:690) 08-22 19:18:10.060: E/AndroidRuntime(17748): at android.view.View.layout(View.java:14118) 08-22 19:18:10.060: E/AndroidRuntime(17748): at android.view.ViewGroup.layout(ViewGroup.java:4467) 08-22 19:18:10.060: E/AndroidRuntime(17748): at android.widget.FrameLayout.onLayout(FrameLayout.java:448) 08-22 19:18:10.060: E/AndroidRuntime(17748): at android.view.View.layout(View.java:14118) 08-22 19:18:10.060: E/AndroidRuntime(17748): at android.view.ViewGroup.layout(ViewGroup.java:4467) 08-22 19:18:10.060: E/AndroidRuntime(17748): at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1670) 08-22 19:18:10.060: E/AndroidRuntime(17748): at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1528) 08-22 19:18:10.060: E/AndroidRuntime(17748): at android.widget.LinearLayout.onLayout(LinearLayout.java:1441) 08-22 19:18:10.060: E/AndroidRuntime(17748): at android.view.View.layout(View.java:14118) 08-22 19:18:10.060: E/AndroidRuntime(17748): at android.view.ViewGroup.layout(ViewGroup.java:4467) 08-22 19:18:10.060: E/AndroidRuntime(17748): at android.widget.FrameLayout.onLayout(FrameLayout.java:448) 08-22 19:18:10.060: E/AndroidRuntime(17748): at android.view.View.layout(View.java:14118) 08-22 19:18:10.060: E/AndroidRuntime(17748): at android.view.ViewGroup.layout(ViewGroup.java:4467) 08-22 19:18:10.060: E/AndroidRuntime(17748): at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2183) 08-22 19:18:10.060: E/AndroidRuntime(17748): at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1947) 08-22 19:18:10.060: E/AndroidRuntime(17748): at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1139) 08-22 19:18:10.060: E/AndroidRuntime(17748): at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4893) 08-22 19:18:10.060: E/AndroidRuntime(17748): at android.view.Choreographer$CallbackRecord.run(Choreographer.java:776) 08-22 19:18:10.060: E/AndroidRuntime(17748): at android.view.Choreographer.doCallbacks(Choreographer.java:579) 08-22 19:18:10.060: E/AndroidRuntime(17748): at android.view.Choreographer.doFrame(Choreographer.java:548) 08-22 19:18:10.060: E/AndroidRuntime(17748): at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:762) 08-22 19:18:10.060: E/AndroidRuntime(17748): at android.os.Handler.handleCallback(Handler.java:800) 08-22 19:18:10.060: E/AndroidRuntime(17748): at android.os.Handler.dispatchMessage(Handler.java:100) 08-22 19:18:10.060: E/AndroidRuntime(17748): at android.os.Looper.loop(Looper.java:194) 08-22 19:18:10.060: E/AndroidRuntime(17748): at android.app.ActivityThread.main(ActivityThread.java:5426) 08-22 19:18:10.060: E/AndroidRuntime(17748): at java.lang.reflect.Method.invokeNative(Native Method) 08-22 19:18:10.060: E/AndroidRuntime(17748): at java.lang.reflect.Method.invoke(Method.java:525) 08-22 19:18:10.060: E/AndroidRuntime(17748): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:842) 08-22 19:18:10.060: E/AndroidRuntime(17748): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:609) 08-22 19:18:10.060: E/AndroidRuntime(17748): at dalvik.system.NativeStart.main(Native Method)

EDIT - 2(搜索框编辑文本):

searchBox.addTextChangedListener(new TextWatcher() {
        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            // TODO Auto-generated method stub

        }
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count,int after) {
            // TODO Auto-generated method stub
            //Log.e("onQueryTextChange","contact beforeTextChanged:"+ s);    
        }
        @Override
        public void afterTextChanged(Editable s) {
            // TODO Auto-generated method stub
            //Log.e("onQueryTextChange","contact afterTextChanged:"+ s);
            try{
                searchText = s.toString();
                if(searchText.length() > 0){
                    mContactListAdapter.getFilter().filter(searchText);    

                }
            }catch(Exception e){
                e.printStackTrace();
            }
            Log.e("onQueryTextChange","contact onTextChanged:"+ s);
        }
    });

【问题讨论】:

  • 你能发布整个堆栈跟踪吗?
  • 感谢堆栈跟踪。你确定你没有从后台线程调用 getFilter 吗?
  • 你能把代码贴在你使用适配器的地方吗?
  • @hoomi:检查编辑。
  • @I-droid 你试过我的代码了吗?

标签: android listview filter illegalstateexception


【解决方案1】:

您的代码的某些部分对我来说没有意义。在performFiltering 方法中,您有以下几行:

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

然后在publishResults 你有以下行:

contactNameList = (ArrayList<String>) results.values;

我认为您要更新contactNameList 的唯一地方是fetchContactData 方法。此方法正在后台线程中调用。而且我相信您在适配器中使用了contactNameList。也是。这就是您收到此错误的原因。请尝试以下方法:

private ArrayList<String> fetchContactData(String query) {
    //Do your query here but DO NOT update contactNameList
    return <the arrayList>
}

然后在您的performFiltering 中替换以下行:

synchronized (this) {
       fetchContactData(sql);            
}

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

用这个:

ArrayList<String> temp;
synchronized (this) {
       temp = fetchContactData(sql);            
}

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

这应该可以解决问题

【讨论】:

  • 是的,我今天刚刚尝试了您的代码,但问题仍然存在。
【解决方案2】:

我认为问题是在 searchBox 中添加快速字符时;它会太快地获取数组中的联系人。意思是 notifyDatasetChanged() 没有足够的时间被调用。所以,我以以下解决方案结束:

 searchBox.addTextChangedListener(new TextWatcher() {

        private final int TRIGGER_SERACH = 1;
        private final long SEARCH_TRIGGER_DELAY_IN_MS = 300;  

        private Handler handler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                if (msg.what == TRIGGER_SERACH) {  
                    try{
                        //if(searchText.length() > 0){  
                            mContactListAdapter.getFilter().filter(searchText);                             
                        //}
                    }catch(Exception e){
                        e.printStackTrace(); 
                    }
                }
            }
        };

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            // TODO Auto-generated method stub

        }  
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count,int after) {
            // TODO Auto-generated method stub
            //Log.e("onQueryTextChange","contact beforeTextChanged:"+ s);   
        }
        @Override
        public void afterTextChanged(Editable s) {
            // TODO Auto-generated method stub
            //Log.e("onQueryTextChange","contact afterTextChanged:"+ s);
            searchText = s.toString();
            handler.removeMessages(TRIGGER_SERACH);
            handler.sendEmptyMessageDelayed(TRIGGER_SERACH, SEARCH_TRIGGER_DELAY_IN_MS);
            Log.e("onQueryTextChange","contact onTextChanged:"+ s);        
        }
    });

这将等待用户完成输入单词,然后才开始搜索。

【讨论】:

    猜你喜欢
    • 2019-09-25
    • 1970-01-01
    • 2018-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-26
    • 2017-07-21
    • 2013-08-27
    相关资源
    最近更新 更多