1

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

错误是:

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(); 

    } 

这是我的logcat:

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 
+0

从这些日志的外观,无论是H在UI线程上开始。你有没有尝试过使用runonuithread内置方法? – KoalaKoalified

回答

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; 
    } 

它应该按预期工作

0
onPostExecute

试试这个:

new Handler().post(new Runnable() 
     { 

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

希望TI可帮助您

相关问题