我正在尝试通过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();
}
这是我的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 :(得分:1)
问题是您在planlist
课程中继续引用Adapterr
,因此当您调用planlist.clear()
方法时,系统会抛出此异常。因此,每当您调用dialog()
方法时,只要实例化适配器,就可以避免在planlist
类中保留对Adapterr
的引用,例如,像这样:
public Adapterr(Context context,ArrayList<HashMap<String, String>> applist){
this.list1 = new ArrayList<HashMap<String, String>>(applist);
this.context = context;
}
它应该按预期工作
答案 1 :(得分:0)
在onPostExecute
中尝试此操作:
new Handler().post(new Runnable()
{
@Override
public void run()
{
dialog();
}
});
希望ti帮助你