在对话框中的 ListView 中获取数据时出错?

Posted

技术标签:

【中文标题】在对话框中的 ListView 中获取数据时出错?【英文标题】:Error while fetching data in ListView in dialog box? 【发布时间】:2016-04-22 00:29:03 【问题描述】:

我正在尝试通过 ListView 中的 JSON 获取数据。现在的问题是当Dialog 第一次打开时,它显示ListView 的数据正确,但是当我关闭Dialog 并尝试再次打开它时,它给了我错误。

错误是:

java.lang.IllegalStateException:适配器的内容发生了变化,但ListView没有收到通知。确保适配器的内容不是从后台线程修改的,而只是从 UI 线程修改的。确保您的适配器在其内容更改时调用 notifyDataSetChanged()

我正在从 AsyncTast 的 UI 线程修改我的适配器,并且我还从 UI 线程调用 notifyDataSetChanged() 方法。但是不知道为什么第二次打开我的对话框给我错误。

那么我该如何解决这个问题呢?

这是我的 AsyncTast 的 onPostExecute 方法:

@Override
protected void onPostExecute(String result) 
    super.onPostExecute(result);
    pDialog.dismiss();
    planlist.clear();
    applist.clear();
    try 
        JSONObject obj = new JSONObject(result);

        String errCode = obj.getString("errCode");

        if(errCode.equalsIgnoreCase("-1"))
            JSONObject object = obj.getJSONObject("scheme");
            JSONObject object1 = object.getJSONObject("mobile");
            String state = object1.getString("state");
            String operator = object1.getString("operator");
            String operator_imag = object1.getString("operator_img");
            System.out.println("lenghtsima>>>>"+(object1.length()-3)+"");
            numberOfPlans = (object1.length())-3;

            for(int i = positionInNumber; i<=positionInNumber;i++) 
                //  System.out.println("Object>>>>"+object1.length()+" objectdata>>"+object1.getJSONObject(Integer.toString(i)));
                JSONObject object2 = object1.getJSONObject(Integer.toString(i));
                String plan_name = object2.getString("plan_name");
                String plan_id = object2.getString("plan_id");
                String operator_plan_id = object2.getString("operator_plan_id");

                app_detail = new HashMap<String, String>();
                app_detail.put("plan_name",plan_name);
                app_detail.put("plan_id",plan_id);
                app_detail.put("operator_plan_id", operator_plan_id);
                applist.add(app_detail);

                JSONArray jsonArray = object2.getJSONArray("planlists");
                for(int j = 0; j<jsonArray.length();j++) 
                    //    System.out.println("ARRAY>>"+jsonArray.length()+" jsonarray="+jsonArray.toString());
                    JSONObject object3 = jsonArray.getJSONObject(j);
                    JSONObject object4 = object3.getJSONObject("OpreatorPlan");
                    String amount = object4.getString("amount");
                    String id = object4.getString("id");
                    String description = object4.getString("description");
                    String validity = object4.getString("talk_time");
                    String recommend_flag = object4.getString("recommend_flag");

                    plan_details = new HashMap<String, String>();
                    plan_details.put("amount",amount);
                    plan_details.put("id",id);
                    plan_details.put("description",description);
                    plan_details.put("validity",validity);
                    plan_details.put("recommend_flag",recommend_flag);
                    planlist.add(plan_details);

                
            
        
        System.out.println("apppppp=" + planlist.toString());

        dialog();

     catch (Exception e) 
        e.printStackTrace();
    


这是我的适配器:

 private class Adapterr extends BaseAdapter 

        ArrayList<HashMap<String, String>> list1;
        Context context;
        public Adapterr(Context context,ArrayList<HashMap<String, String>> applist)
            this.list1 = applist;
            this.context = context;
        

        @Override
        public int getCount() 
            return list1.size();
        

        @Override
        public Object getItem(int position) 
            return list1.get(position);
        

        @Override
        public long getItemId(int position) 
            return position;
        

        @Override
        public View getView(final int position, View convertView, ViewGroup parent) 
            final LayoutInflater inflater = getLayoutInflater();
            final MyViewHolderTwo myViewHolderTwo;
            if(convertView==null)
                convertView = inflater.inflate(R.layout.operator_plans,parent,false);
                myViewHolderTwo = new MyViewHolderTwo(convertView);
                convertView.setTag(myViewHolderTwo);
            else
                myViewHolderTwo = (MyViewHolderTwo) convertView.getTag();
            

            HashMap<String, String> map = list1.get(position);
            String amount = map.get("amount");
        //    String id = map.get("id");
            String description = map.get("description");
            String validity = map.get("validity");
         //   String recommend_flag = map.get("recommend_flag");

            myViewHolderTwo.amount.setText(amount);
            myViewHolderTwo.validity.setText(validity);
            myViewHolderTwo.description.setText(description);


            return convertView;
        
    

    private class MyViewHolderTwo 
        TextView amount,validity,description;

        public MyViewHolderTwo(View item) 
            amount = (TextView)item.findViewById(R.id.amount);
            validity = (TextView)item.findViewById(R.id.validity);
            description = (TextView)item.findViewById(R.id.description);
        
    

这是我的对话:

 public void dialog()
        dlg = new Dialog(BrowseOperatorsPlans.this);
        dlg.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dlg.setContentView(R.layout.browse_operator_plans_dialog);
        TextView dialog_header = (TextView)dlg.findViewById(R.id.dialog_header_title);
        ImageView close = (ImageView)dlg.findViewById(R.id.close_dialog);


        listView1 = (ListView)dlg.findViewById(R.id.listview_horizontal);

        adapterr = new Adapterr(getBaseContext(),planlist);
        listView1.setAdapter(adapterr);
        adapterr.notifyDataSetChanged();
      //  listView1.requestLayout();

        close.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View v) 
                dlg.dismiss();
            
        );

        dlg.getWindow().setLayout(WindowManager.LayoutParams.MATCH_PARENT, 500);
        dialog_header.setText("Select Plan");
        dlg.getWindow().setBackgroundDrawable(
                new ColorDrawable(
                        android.graphics.Color.TRANSPARENT));
        dlg.show();

    

这是我的日志:

01-16 18:47:21.302 30604-30604/com.example.admin.smsrupee E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.admin.smsrupee, PID: 30604
    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(2131558551, class android.widget.ListView) with Adapter(class com.example.admin.smsrupee.BrowseOperatorsPlans$Adapter)]
        at android.widget.ListView.layoutChildren(ListView.java:1565)
        at android.widget.AbsListView.onTouchUp(AbsListView.java:3843)
        at android.widget.AbsListView.onTouchEvent(AbsListView.java:3604)
        at android.view.View.dispatchTouchEvent(View.java:7782)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2316)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2013)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2322)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2027)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2322)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2027)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2322)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2027)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2322)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2027)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2322)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2027)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2322)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2027)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2322)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2027)
        at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2109)
        at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1541)
        at android.app.Activity.dispatchTouchEvent(Activity.java:2491)
        at android.support.v7.internal.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:60)
        at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2057)
        at android.view.View.dispatchPointerEvent(View.java:7973)
        at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4549)
        at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4420)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3966)
        at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4016)
        at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3985)
        at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4092)
        at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3993)
        at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4149)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3966)
        at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4016)
        at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3985)
        at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3993)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3966)
        at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:6298)
        at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:6261)
        at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:6215)
        at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:6443)
        at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:185)
        at android.os.MessageQueue.nativePollOnce(Native Method)
        at android.os.MessageQueue.next(MessageQueue.java:138)
        at android.os.Looper.loop(Looper.java:150)
        at android.app.ActivityThread.main(ActivityThre
01-16 18:48:10.828 30604-30676/com.example.admin.smsrupee D/dalvikvm: threadid=15: exiting
01-16 18:48:10.829 30604-30676/com.example.admin.smsrupee D/dalvikvm: threadid=15: detach (group=0x4183bce0)
01-16 18:48:10.829 30604-30676/com.example.admin.smsrupee D/dalvikvm: threadid=15: removing from list
01-16 18:48:10.830 30604-30676/com.example.admin.smsrupee D/dalvikvm: threadid=15: bye!
01-16 18:52:21.343 30604-30604/com.example.admin.smsrupee I/P

【问题讨论】:

从这些日志的外观来看,UI线程上都没有发生。您是否尝试过使用 runonuithread 内置方法? 【参考方案1】:

问题是你在你的Adapterr 类中一直引用你的planlist,所以当你调用planlist.clear() 方法时,就会抛出这个异常。因此,当您每次调用 dialog() 方法时都实例化适配器时,您可以避免在 Adapterr 类中保留对 planlist 的引用,例如,如下所示:

    public Adapterr(Context context,ArrayList<HashMap<String, String>> applist)
        this.list1 = new ArrayList<HashMap<String, String>>(applist);
        this.context = context;
    

它应该按预期工作

【讨论】:

【参考方案2】:

onPostExecute 试试这个:

new Handler().post(new Runnable() 
        

            @Override
            public void run() 
            
                dialog();
            
        );

希望对你有帮助

【讨论】:

以上是关于在对话框中的 ListView 中获取数据时出错?的主要内容,如果未能解决你的问题,请参考以下文章

将项目从对话框添加到 ListView

无法通过 ListView 搜索,返回零结果

如何在 ListView 中使用 onItemClickListener 获取其他列

JSONArray 到 ListView - AsyncTask

如何在单击android中的listview项目时从数据库中获取id

在Android中更新firebase数据库时ListView值重复值