继续获取ListView的内容已更改...错误

时间:2015-01-23 14:57:53

标签: android listview android-listview

我已多次修改我的代码以避免此错误,每次我触摸我的listview适配器时都是来自UI线程。我做的是我做了一个异步任务来获取listview所需的数据。 On" PostExecute"我调用静态方法来处理之后需要处理的操作。我不时地得到报告,应用程序使用ListView在片段上崩溃。它不一致所以很难再现,但我想知道如何修复?也许我可以抓住错误并要求用户再次刷新,但我认为不可能。这是我的代码触及我的适配器。

    public static void refresh() {
    Log.i("Handling Refresh", "Handling");
    HandleRefresh handleRefresh = new HandleRefresh(Util.tabbedActivity);

    if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.HONEYCOMB)
        handleRefresh.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
    else
        handleRefresh.execute();

}

处理刷新

public class HandleRefresh extends AsyncTask<String, String, String> {

Context context;
String response;
public HandleRefresh(Context context)
{
    this.context = context;
}

@Override
protected String doInBackground(String... params) {
    final LoadEvents loadEvents = new LoadEvents(Util.tabbedActivity.getApplicationContext(), 1);


    try{
        response = loadEvents.execute().get();

        Log.i("Response ", response);
        if(response.equals("A"))
        {



            Log.d("Loading Events: ", "1 Events Loaded" + " " + AdapterUtilities.posts.size());


            AdapterUtilities.sortPosts();

            Log.i("Loading Events:", " " + AdapterUtilities.posts.size());



            AdapterUtilities.ORIGINALPOSTSLISTS.addAll(AdapterUtilities.POSTSLISTS);
            AdapterUtilities.Originalposts.addAll(AdapterUtilities.posts);
            AdapterUtilities.OriginalTIMELIST.addAll(AdapterUtilities.TIMELIST);

            Calendar cal = Calendar.getInstance();
            Long realTime = cal.getTimeInMillis();

            AdapterUtilities.REALTIME = realTime;
            for (int i = 0; i < AdapterUtilities.POSTSLISTS.size(); i++) {
                Log.d("Loading Events: ", "PRE LOAD : " + AdapterUtilities.POSTSLISTS.get(i).get(AdapterUtilities.EVENTID));
            }





            Log.d("Loading Events: ", "2 Events Loaded" + " " + AdapterUtilities.posts.size());




            Util.saveToSharedPrefsInteger(Util.tabbedActivity.getApplicationContext(), "LN", 1);

            try {


            } catch (IllegalStateException ise) {
                ise.printStackTrace();
            }




        }
        else if (response.equals("D"))
        {

            return "D";
        }
        else
        {


            return "C";


        }
    } catch (InterruptedException e) {
        e.printStackTrace();
    } catch (ExecutionException e) {
        e.printStackTrace();
    }
    return "C";
}


@Override
protected void onPostExecute(String o)
{
    MainFeed.setMainFeed(response);
}
}

这是setMainFeed,触及listview和适配器的方法。我等待后台线程的回复然后我做我的行动。

    public static void setMainFeed(String response)
{



    Log.i("Handle refresh response", response);
    if(response.equals("A"))
    {
        lv.setAdapter(adapter);

        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    final EventUtils EventUtils = new EventUtils(Util.tabbedActivity);

                    EventUtils.runRefresh(EventUtils.REDO_LISTS);

                    Util.tabbedActivity.runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Log.i("EVENTS TO RATE ", "EVENTS TO RATE = " + RateEventNode.EVENTS_TO_RATE);

                            if (RateEventNode.EVENTS_TO_RATE != 0) {

                                MainFeed.showRateDialog(EventUtils.EVENTSTORATELIST.get(RateEventNode.EVENTS_TO_RATE - 1));

                            }
                        }
                    });
                } catch (ExecutionException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
        }).start();




        if(mainFeedLayoutsVF.getDisplayedChild() == 1) {
            mainFeedLayoutsVF.setDisplayedChild(0);
        }
        final ImageView failedRefreshButton = (ImageView) view.findViewById(R.id.failedRefreshButtonWhite);
        failedRefreshButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                actionRefresh.setActionView(abprogress);
                failedRefreshButton.setVisibility(View.INVISIBLE);
                refresh();
            }
        });






        swipeLayout.setRefreshing(false);



        EventUtils.enableServicesAndReceivers(Util.tabbedActivity);



        Log.i("LV ", "LV  " + lv.getAdapter().toString());

        if(actionRefresh != null) {
            actionRefresh.setActionView(null);
        }








    }
    else if(response.equals("D"))
    {

        if(mainFeedLayoutsVF.getDisplayedChild() == 0) {
            mainFeedLayoutsVF.setDisplayedChild(1);
        }

        if(actionRefresh != null) {
            actionRefresh.setActionView(null);
        }
        final ImageView failedRefreshButton = (ImageView) view.findViewById(R.id.failedRefreshButtonWhite);
        failedRefreshButton.setVisibility(View.INVISIBLE);

        failedRefreshTV.setText("Whoops! Looks like you aren't following anyone. Go to the DISCOVER tab to get connected.");


        failedRefreshButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                actionRefresh.setActionView(abprogress);
                failedRefreshButton.setVisibility(View.INVISIBLE);
                refresh();
            }
        });
    }
    else
    {

        if(mainFeedLayoutsVF.getDisplayedChild() == 0) {
            mainFeedLayoutsVF.setDisplayedChild(1);
        }

        if(actionRefresh != null) {
            actionRefresh.setActionView(null);
        }

        final ImageView failedRefreshButton = (ImageView) view.findViewById(R.id.failedRefreshButtonWhite);
        failedRefreshButton.setVisibility(View.VISIBLE);

        failedRefreshTV.setText(Util.tabbedActivity.getString(R.string.couldNotConnect));

        failedRefreshButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                actionRefresh.setActionView(abprogress);
                failedRefreshButton.setVisibility(View.INVISIBLE);
                refresh();
            }
        });

    }
}

这是LogCat

01-23 09:47:56.283  18567-18567/com.android.wallfly E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.android.wallfly, PID: 18567
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. Make sure your adapter calls notifyDataSetChanged() when its content changes. [in ListView(2131362088, class android.widget.ListView) with Adapter(class android.widget.HeaderViewListAdapter)]
        at android.widget.ListView.layoutChildren(ListView.java:1566)
        at android.widget.AbsListView.onLayout(AbsListView.java:2528)
        at android.view.View.layout(View.java:15655)
        at android.view.ViewGroup.layout(ViewGroup.java:4856)
        at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1055)
        at android.view.View.layout(View.java:15655)
        at android.view.ViewGroup.layout(ViewGroup.java:4856)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:388)
        at android.view.View.layout(View.java:15655)
        at android.view.ViewGroup.layout(ViewGroup.java:4856)
        at android.support.v4.widget.SwipeRefreshLayout.onLayout(SwipeRefreshLayout.java:543)
        at android.view.View.layout(View.java:15655)
        at android.view.ViewGroup.layout(ViewGroup.java:4856)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:388)
        at android.view.View.layout(View.java:15655)
        at android.view.ViewGroup.layout(ViewGroup.java:4856)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:388)
        at android.view.View.layout(View.java:15655)
        at android.view.ViewGroup.layout(ViewGroup.java:4856)
        at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1677)
        at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1531)
        at android.widget.LinearLayout.onLayout(LinearLayout.java:1440)
        at android.view.View.layout(View.java:15655)
        at android.view.ViewGroup.layout(ViewGroup.java:4856)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:388)
        at android.view.View.layout(View.java:15655)
        at android.view.ViewGroup.layout(ViewGroup.java:4856)
        at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1055)
        at android.view.View.layout(View.java:15655)
        at android.view.ViewGroup.layout(ViewGroup.java:4856)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:388)
        at android.view.View.layout(View.java:15655)
        at android.view.ViewGroup.layout(ViewGroup.java:4856)
        at com.android.internal.widget.ActionBarOverlayLayout.onLayout(ActionBarOverlayLayout.java:438)
        at android.view.View.layout(View.java:15655)
        at android.view.ViewGroup.layout(ViewGroup.java:4856)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:388)
        at android.view.View.layout(View.java:15655)
        at android.view.ViewGroup.layout(ViewGroup.java:4856)
        at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2282)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2002)
        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1234)
        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6465)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:803)
        at android.view.Choreographer.doCallbacks(Choreographer.java:603)
        at android.view.Choreographer.doFrame(Choreographer.java:573)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:789)
        at android.os.Handler.handleCallback(Handler.java:733)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:157)
        at android.app.ActivityThread.main(ActivityThread.java:5356)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:515)
        at com.android.internal.os.Zygot

我做错了什么?

1 个答案:

答案 0 :(得分:1)

如果您碰巧更改了输入适配器的基础数据,我怀疑您可能正在使用

AdapterUtilities.ORIGINALPOSTSLISTS.addAll(AdapterUtilities.POSTSLISTS); 
AdapterUtilities.Originalposts.addAll(AdapterUtilities.posts);   
AdapterUtilities.OriginalTIMELIST.addAll(AdapterUtilities.TIMELIST);

每当您更改适配器中显示的数据时,您都必须致电notifyDatasetChanged(),请参阅base adapter docs