Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/317.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
Java ListFragment IllegalStateException:“;适配器的内容已更改,但ListView未收到通知;_Java_Android_Multithreading_Android Fragments_Illegalstateexception - Fatal编程技术网

Java ListFragment IllegalStateException:“;适配器的内容已更改,但ListView未收到通知;

Java ListFragment IllegalStateException:“;适配器的内容已更改,但ListView未收到通知;,java,android,multithreading,android-fragments,illegalstateexception,Java,Android,Multithreading,Android Fragments,Illegalstateexception,我读了一些关于这个问题的答案,但我不知道如何将解决方案应用到我的问题上 为了说明问题何时发生,我有一个ViewPager,它有3个选项卡,每个选项卡对应一个片段。第一个片段有一个ListView。当我在另外两个选项卡之间快速滑动时,我的应用程序崩溃,我得到这个错误。我知道我的片段会继续被重新加载,并且发生在哪里。不过我不知道怎么修 有关守则: @Override public void onActivityCreated(Bundle savedInstanceState) { supe

我读了一些关于这个问题的答案,但我不知道如何将解决方案应用到我的问题上

为了说明问题何时发生,我有一个ViewPager,它有3个选项卡,每个选项卡对应一个片段。第一个片段有一个ListView。当我在另外两个选项卡之间快速滑动时,我的应用程序崩溃,我得到这个错误。我知道我的片段会继续被重新加载,并且发生在哪里。不过我不知道怎么修

有关守则:

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

    feed = getListView();

    feedItems = new ArrayList<FeedItem>();
    listAdapter = new FeedListAdapter(getActivity(), feedItems);
    feed.setAdapter(listAdapter);

    new Thread(new Runnable() {
        public void run() {
            for (int i = 0; i < 9; i++) {
                FeedItem item = new FeedItem("Status " + i);

                feedItems.add(item);
           }

           getActivity().runOnUiThread(new Runnable() {
               public void run() {
                   listAdapter.notifyDataSetChanged();
               }
           }
        }
    }).start();
}
@覆盖
已创建ActivityState上的公共无效(Bundle savedInstanceState){
super.onActivityCreated(savedInstanceState);
feed=getListView();
feedItems=新的ArrayList();
listAdapter=新的FeedListAdapter(getActivity(),feedItems);
feed.setAdapter(listAdapter);
新线程(newrunnable()){
公开募捐{
对于(int i=0;i<9;i++){
饲料项目=新饲料项目(“状态”+i);
添加(项目);
}
getActivity().runOnUiThread(新的Runnable()){
公开募捐{
listAdapter.notifyDataSetChanged();
}
}
}
}).start();
}
上面的代码是关于堆栈溢出如何在不同线程之间分割内容(在工作线程上处理,然后在UI线程上通知或执行UI更改)的教科书

罪魁祸首是feedItems.add(item);

我读过关于在UI线程中将项目添加到ArrayList中的内容,但是如果我一次添加一个项目,感觉好像每次循环迭代都会在后台线程和UI线程之间来回跳转。一个快速的解决方案是只需有两个ArrayList,一个在for循环中使用,另一个最终使用当我基本上将一个ArrayList复制到另一个ArrayList,然后
listAdapter.notifyDataSetChanged();

我不能说我特别喜欢上面的解决方案。它似乎有点俗气。从本质上说,这感觉像是一个多线程问题,我根本不想在通知适配器更改之前通过将ArrayList复制到另一个ArrayList来备份UI线程。就我个人而言,我认为我需要在某个地方进行一些同步,但我是新手但我不知道该怎么做


我认为,一个答案将非常清楚,并且对许多遇到这种情况的人也非常有益。

您需要在
runOnUiThread()
方法中更新您的UI。因此,只需使用该方法设置适配器即可

因此,您的最终代码将是

 getActivity().runOnUiThread(new Runnable() {
           public void run() {
               listAdapter = new FeedListAdapter(getActivity(), feedItems);
               feed.setAdapter(listAdapter);
               listAdapter.notifyDataSetChanged();
           }
 }

这是在UI线程上设置的。它位于
新线程(new Runnable(){
行)上方。否。您不需要在该行上方执行写入操作。您的listview将在
runanuithread
方法中更新。因此,只需在
runanuithread
方法中的listview中设置适配器,而不是在
新线程(new Runnable()中设置适配器{
行。好吧,好消息是它解决了这个问题。我不明白为什么它解决了这个问题。是的,做了你建议的更改就消除了错误。我不明白为什么。这是因为你的
UI
无法在主线程中更新。所以你需要在
runOnUiThread()中更新
方法,当您使用
AsyncTask
时,您的UI将在
onPostExecute()
方法中更新。