繁体   English   中英

java.lang.IllegalStateException-为什么? (Android,ListAdapter)

[英]java.lang.IllegalStateException - why??? (Android, ListAdapter)

用户有时会收到以下异常(我自己无法重现):

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(2131165209, class android.widget.ListView) with Adapter(class com.tfd.mobile.TfdSearch.TfdSearch$SearchList$PagesListAdapter)]
at android.widget.ListView.layoutChildren(ListView.java:1567)
at android.widget.AbsListView.onTouchModeChanged(AbsListView.java:2093)
at android.view.ViewTreeObserver.dispatchOnTouchModeChanged(ViewTreeObserver..java:591)
at android.view.ViewRoot.ensureTouchModeLocally(ViewRoot.java:2023)
at android.view.ViewRoot.ensureTouchMode(ViewRoot.java:2007)
at android.view.ViewRoot.handleMessage(ViewRoot.java:1775)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:4633)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:521)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
at dalvik.system.NativeStart.main(Native Method)

我找不到原因。 我使用线程,但是主线程中的所有基础数​​据都发生了变化。 而且我总是叫_adapter.notifyDataSetChanged(); 数据更改后。 请帮我! 这是我的代码:

    private class SearchList extends LinkedList<PageInfo>
{
    private static final long serialVersionUID = 1L;

    private PagesListAdapter _adapter;

    public PagesListAdapter getAdapter()
    {
        return _adapter;
    }

    public SearchList(ListView listView)
    {
        super();
        _adapter = new PagesListAdapter(activity, this);
        listView.setAdapter(_adapter);
    }

    private void getSuggestions(final String typedText)
    {
        showProgressVisibility(true);
        new Thread(new Runnable() {

            public void run() {
                android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND);
                final String[] sugg = TfdMode.getMode().getSuggestions(typedText);

                activity.runOnUiThread(new Runnable() {
                    public void run() {
                        if (sugg != null)
                        {
                            clear();
                            for (String s: sugg) {
                                add(new PageInfo(s, PageInfo.PAGE_SUGGESTION, null));
                            }
                        }
                        _adapter.notifyDataSetChanged();
                        showProgressVisibility(false);
                    }
                });
            }
        }).start();
    }

    public void refresh(final String typedText)
    {
        if (typedText.length() >= 3)
        {
            // use suggestions (separate thread)
            getSuggestions(typedText);
        }
        else
        {
            // use recent
            clear();
            for (PageInfo p: TfdMode.getMode().recentManager.pages) {
                if (p.text.startsWith(typedText)) add(p);
            }

            if (size() == 0 && typedText.length() > 0)
                getSuggestions(typedText);  // if no recent - use suggestions
            else
                _adapter.notifyDataSetChanged();
        }

    }


    public class PagesListAdapter extends ArrayAdapter<PageInfo> {

        private LayoutInflater mInflater;

        public PagesListAdapter(Context context, List<PageInfo> objects) {
            super(context, R.layout.bookmarks_item, R.id.bookmark_title, objects);
            mInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {   

            final PageInfo b = getItem(position);
            View row = convertView == null ?  mInflater.inflate(R.layout.bookmarks_item, null) : convertView;

            TextView title = (TextView) row.findViewById(R.id.bookmark_title);
            ImageView img = (ImageView) row.findViewById(R.id.bookmark_img);
            ImageView del = (ImageView) row.findViewById(R.id.bookmark_img_del);
            del.setVisibility(View.GONE);

            title.setText(b.text);
            int iconId = b.getIconResId(); 

            if (iconId != -1)
            {
                img.setImageResource(iconId);
                img.setVisibility(View.VISIBLE);
            }
            else
                img.setVisibility(View.INVISIBLE);


            return row;
        }
    }


};

更改数据的唯一位置-调用“刷新”方法时。 它总是从主线程调用。 为什么它仍然发生??? 救命!

何时确切出现java.lang.IllegalStateException异常? ** **当我从非UI线程明确运行“刷新”方法时,在_adapter.notifyDataSetChanged()调用时,我得到另一个异常(CalledFromWrongThreadException):

10-12 13:20:29.057: ERROR/AndroidRuntime(24746): FATAL EXCEPTION: Thread-27
10-12 13:20:29.057: ERROR/AndroidRuntime(24746): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
10-12 13:20:29.057: ERROR/AndroidRuntime(24746):     at android.view.ViewRoot.checkThread(ViewRoot.java:2837)
10-12 13:20:29.057: ERROR/AndroidRuntime(24746):     at android.view.ViewRoot.invalidateChild(ViewRoot.java:619)
10-12 13:20:29.057: ERROR/AndroidRuntime(24746):     at android.view.ViewRoot.invalidateChildInParent(ViewRoot.java:645)
10-12 13:20:29.057: ERROR/AndroidRuntime(24746):     at android.view.ViewGroup.invalidateChild(ViewGroup.java:2505)
10-12 13:20:29.057: ERROR/AndroidRuntime(24746):     at android.view.View.invalidate(View.java:5192)
10-12 13:20:29.057: ERROR/AndroidRuntime(24746):     at android.view.View.setFlags(View.java:4569)
10-12 13:20:29.057: ERROR/AndroidRuntime(24746):     at android.view.View.setVisibility(View.java:3083)
10-12 13:20:29.057: ERROR/AndroidRuntime(24746):     at com.tfd.mobile.TfdSearch.TfdSearch.showProgressVisibility(TfdSearch.java:315)
10-12 13:20:29.057: ERROR/AndroidRuntime(24746):     at com.tfd.mobile.TfdSearch.TfdSearch.access$0(TfdSearch.java:313)
10-12 13:20:29.057: ERROR/AndroidRuntime(24746):     at com.tfd.mobile.TfdSearch.TfdSearch$SearchList.getSuggestions(TfdSearch.java:783)
10-12 13:20:29.057: ERROR/AndroidRuntime(24746):     at com.tfd.mobile.TfdSearch.TfdSearch$SearchList.refresh(TfdSearch.java:823)
10-12 13:20:29.057: ERROR/AndroidRuntime(24746):     at com.tfd.mobile.TfdSearch.TfdSearch$8$1.run(TfdSearch.java:443)
10-12 13:20:29.057: ERROR/AndroidRuntime(24746):     at java.lang.Thread.run(Thread.java:1096)

您必须从UI线程(可能不是主线程)中调用refresh。 您可以使用它在UI线程上运行某些内容:

Activity.runOnUiThread(Runnable)

-> http://developer.android.com/reference/android/app/Activity.html#runOnUiThread%28java.lang.Runnable%29

_adapter.notifyDataSetChanged();

这必须在UI线程上执行。 使用处理程序或runOnUiThread

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM