Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/224.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 安卓ArrayAdapter。“适配器的内容已更改,但ListView未收到通知。”_Android_Listview_Android Arrayadapter - Fatal编程技术网

Android 安卓ArrayAdapter。“适配器的内容已更改,但ListView未收到通知。”

Android 安卓ArrayAdapter。“适配器的内容已更改,但ListView未收到通知。”,android,listview,android-arrayadapter,Android,Listview,Android Arrayadapter,我对listview有问题。某些用户发生以下跟踪的崩溃: 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 thr

我对listview有问题。某些用户发生以下跟踪的崩溃:

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(16908298, class android.widget.ListView) with Adapter(class com.a.b.c)]
   at android.widget.ListView.layoutChildren(ListView.java:1779)
   at android.widget.AbsListView.onTouchEvent(AbsListView.java:3264)
   at android.widget.ListView.onTouchEvent(ListView.java:4098)
   at android.view.View.dispatchTouchEvent(View.java:5568)
   at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2069)
   at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1737)
   at android.widget.AbsListView.dispatchTouchEvent(AbsListView.java:6272)
   at android.widget.ListView.dispatchTouchEvent(ListView.java:4820)
   at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2075)
   at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1751)
   at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2075)
   at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1751)
   at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2075)
   at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1751)
   at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2075)
   at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1751)
   at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2075)
   at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1751)
   at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2075)
   at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1751)
   at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1998)
   at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1410)
   at android.app.Activity.dispatchTouchEvent(Activity.java:2433)
   at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1946)
   at android.view.View.dispatchPointerEvent(View.java:5748)
   at android.view.ViewRootImpl.deliverPointerEvent(ViewRootImpl.java:3170)
   at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2724)
   at android.view.ViewRootImpl.processInputEvents(ViewRootImpl.java:951)
   at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:965)
   at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2700)
   at android.os.Handler.dispatchMessage(Handler.java:99)
   at android.os.Looper.loop(Looper.java:156)
   at android.app.ActivityThread.main(ActivityThread.java:5109)
但我确信ArrayList中的内容没有改变。代码:

public class ArchivedEventListFragment extends ListFragment {

    ArrayList<Event> mEvents;
    ...
    EventArrayAdapter mEventsAdapter;
    DataManager mDataManager;

    ...

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRetainInstance(true);
        mDataManager = DataManager.get(getActivity());
        ...
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.archive_list_fragment, container, false);
        ...
        return view;
    }


    @Override
    public void onResume() {
        super.onResume();
        if (mEvents == null) {
            mEvents = mDataManager.getArchivedEvents();
            if (mEvents.isEmpty()) {
                new DownloadArchive().execute();
            } else if (mEventsAdapter == null) {
                mEventsAdapter = new EventArrayAdapter(mEvents);
                setListAdapter(mEventsAdapter);
            } else if (getListAdapter() == null) {
                setListAdapter(mEventsAdapter);
            } else {
                mEventsAdapter.notifyDataSetChanged();
            }
        }
        if (getListAdapter() != null && mEventsAdapter != null) {
            mEventsAdapter.notifyDataSetChanged();
        }

        getListView().clearChoices();
        ...
    }

    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        ...
    }

    static class ViewHolderItem {

        ...
    }

    private class EventArrayAdapter extends ArrayAdapter<Event> {

        private final ArrayList<Event> events;

        public EventArrayAdapter(ArrayList<Event> sourceEvents) {
            super(getActivity(), 0, sourceEvents);

            events = sourceEvents;
        }

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

            ViewHolderItem viewHolder;

            if (convertView == null) {
                LayoutInflater inflater = (LayoutInflater)getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                convertView = inflater.inflate(R.layout.event_list_item, parent, false);

                ...

                convertView.setTag(viewHolder);
            } else {
                viewHolder = (ViewHolderItem) convertView.getTag();
            }

            Event event = getItem(position);

            ...
            return convertView;
        }

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

        @Override
        public Event getItem(int position) {
            return events.get(position);
        }
    }

    private class DownloadArchive extends AsyncTask<Void, Void, ArrayList<Event>> {
        @Override
        protected ArrayList<Event> doInBackground(Void... params) {
            return mDataManager.getArchivedEvents();
        }

        @Override
        protected void onPreExecute() {
            setListAdapter(null);
            mEventsAdapter = null;
            super.onPreExecute();
        }

        @Override
        protected void onPostExecute(ArrayList<Event> result) {
            super.onPostExecute(result);
            if (isAdded()) {
                mEvents = result;
                if (!(mEvents.isEmpty())) {
                    mEventsAdapter = new EventArrayAdapter(mEvents);
                    setListAdapter(mEventsAdapter);
                } else {
                    try {
                        Toast.makeText(getActivity(), "Error", Toast.LENGTH_SHORT).show();
                    } catch (Exception e) {
                    }
                    mDataManager.clearEvents();
                    new DownloadArchive().execute();
                }
            }
        }
    }

    ...
}


我尝试在代码中的任何地方调用adpater.notifydatasetchanget,但没有任何帮助。请帮助我了解哪里是我的错。

我对程序中的逻辑有很多问题。如果你愿意,我可以检查一下。但是,既然你问了一个具体的问题,我就在这里做一些假设。似乎您有一些存储事件的单例对象数据管理器。我认为正在发生的是,在其他地方,在其他类中,您正在修改mDataManager中的事件。因为那里的事件列表支持适配器中存储的事件列表,所以Android抱怨您在没有通知的情况下更新了列表。我向DataManager询问了一次事件,并将它们保存在新的ArrayList中。在这段代码中,为什么DataManager ArrayList中的更改可能会影响ArrayList?我希望您了解一点java。关键是,实际上您可能只创建了一个ArrayList。你有多少次新的ArrayList?可能只有在DataManager中。在您发布的代码中,您从未实际创建过新的ArrayList。因此,这里的适配器实际上在使用DataManager中的ArrayList。如果您在其他任何地方,在任何其他代码中更新该ArrayList,都会在这里产生问题。我认为ArrayList mEvents;mEvents=mDataManager.getArchivedEvents;创建一个新的ArrayList并从DataManager复制数据。实际上,它并不创建新的列表,mEvents只指向DataManager返回的ArrayList。假设您有对象o1=新对象,对象o2=o1。显然,只有一个对象,只有一个新语句。o2只是指向与o1相同的对象。这就是你的情况。