android -java.lang.IllegalStateException:适配器的内容已更改但ListView未收到适配器的通知

时间:2014-11-02 06:58:41

标签: android android-listview

我在不同版本的Android和不同的设备上出现此错误。我已经在我自己的几个设备上测试它并没有得到这个问题,但在某些设备上它一直显示我这个错误

这是ListAdapter代码:

ListAdapter ladap;

private class GetContacts extends AsyncTask<Void, Void, Void> { 
    @Override
    protected Void doInBackground(Void... arg0) {
        Spots_tab1_json sh = new Spots_tab1_json();
        String jsonStr = sh.makeServiceCall(url + page, Spots_tab1_json.GET);

        if (jsonStr != null) {
            try {
                JSONObject jsonObj = new JSONObject(jsonStr);
                contacts = jsonObj.getJSONArray(TAG_CONTACTS);

                    for (int i = 0; i < contacts.length(); i++) {
                    JSONObject c = contacts.getJSONObject(i);
                    String id = new String(c.getString("id").getBytes("ISO-8859-1"), "UTF-8");
                    String dates = new String(c.getString("dates").getBytes("ISO-8859-1"), "UTF-8");
                    String price = new String(c.getString("gheymat").getBytes("ISO-8859-1"), "UTF-8");
                    HashMap<String, String> contact = new HashMap<String, String>();
                    contact.put("id", id);
                    contact.put("dates", dates);
                    contact.put("price", price);
                    contactList.add(contact);
                }
                }
            } catch (JSONException e) {
                goterr = true;
            } catch (UnsupportedEncodingException e) {
                goterr = true;
            }
        } else {
            goterr = true;
        }
        return null;
    }

    @Override
    protected void onPostExecute(Void result) {
        super.onPostExecute(result);
        if (!isCancelled() && goterr == false) {
            if(ladap==null){
                ladap=new ListAdapter(MainActivity.this, contactList);
                lv.setAdapter(ladap);
            }else{
                ladap.addAll(contactList);
            }
    }
}


public class ListAdapter extends BaseAdapter {
    Activity activity;
    public ArrayList<HashMap<String, String>> list;

    public ListAdapter(Activity activity,ArrayList<HashMap<String, String>> list) {
        super();
        this.activity = (Activity) activity;
        this.list = list;
    }

    public void addAll(ArrayList<HashMap<String, String>> contactList) {
        this.list = contactList;
        notifyDataSetChanged();
    }

    public int getCount() {
        return contactList.size();
    }

    public Object getItem(int position) {
        return contactList.get(position);
    }

    public long getItemId(int arg0) {
        return 0;
    }

    private class ViewHolder {
        TextView title,price;
        ImageView img ; 
        //RelativeLayout rl; 
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        LayoutInflater inflater = activity.getLayoutInflater();
        if (convertView == null) {
            convertView = inflater.inflate(R.layout.item, null);
            holder = new ViewHolder();
            holder.title = (TextView) convertView.findViewById(R.id.title);
            holder.price = (TextView) convertView.findViewById(R.id.price);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

            item = contactList.get(position);
            holder.price.setText(item.get("price"));
        return convertView;
    }
}

在上面的代码中,当谈到onpostExcecute()时,它会检查ladab是否为null,如果它为null,它会进入并生成ListAdapter(我已记录并且它只出现一次)之后,它涉及addAll方法并向Adapter添加新项目。

这是日志:

STACK_TRACE = 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. [in ListView(2131034188, class android.widget.ListView) with Adapter(class xx.xx.MainActivity$ListAdapter)]
at android.widget.ListView.layoutChildren(ListView.java:1517)
at android.widget.AbsListView.onLayout(AbsListView.java:1925)
at android.view.View.layout(View.java:7462)
at android.widget.RelativeLayout.onLayout(RelativeLayout.java:962)
at android.view.View.layout(View.java:7462)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1268)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1140)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1057)
at android.view.View.layout(View.java:7462)
at android.widget.FrameLayout.onLayout(FrameLayout.java:338)
at android.view.View.layout(View.java:7462)
at android.support.v4.widget.DrawerLayout.onLayout(DrawerLayout.java:743)
at android.view.View.layout(View.java:7462)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1268)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1140)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1057)
at android.view.View.layout(View.java:7462)
at android.widget.FrameLayout.onLayout(FrameLayout.java:338)
at android.view.View.layout(View.java:7462)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1268)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1140)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1057)
at android.view.View.layout(View.java:7462)
at android.widget.FrameLayout.onLayout(FrameLayout.java:338)
at android.view.View.layout(View.java:7462)
at android.widget.FrameLayout.onLayout(FrameLayout.java:338)
at android.view.View.layout(View.java:7462)
at android.view.ViewRoot.performTraversals(ViewRoot.java:1140)
at android.view.ViewRoot.handleMessage(ViewRoot.java:1859)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3694)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
at dalvik.system.NativeStart.main(Native Method)

这段代码有什么问题?我已尽我所能,但我没有设法解决它。

你可以帮我/

谢谢

2 个答案:

答案 0 :(得分:1)

我的代码有点混乱:

    if (!isCancelled() && goterr == false) {
        if(ladap==null){
            ladap=new ListAdapter(MainActivity.this, contactList);
            lv.setAdapter(ladap);
        }else{
            ladap.addAll(contactList);
        }
}

让我们说,代码第一次运行,其中:

isCancelled()是假的

goterr是假的

ladap将为null,因为尚未创建。

如果这3个发生,ladap.addAll(contactList);被调用,因为if(ladap==null)true

尝试这样做:

    if (!isCancelled() && goterr == false) {
        if(ladap==null){
            ladap=new ListAdapter(MainActivity.this, contactList);
            lv.setAdapter(ladap);
        }
        ladap.addAll(contactList); //no neet for else

}

<强>更新

试试这个:

    if (!isCancelled() && goterr == false) {
        if(ladap==null){
            ladap=new ListAdapter(MainActivity.this, contactList);
            lv.setAdapter(ladap);
        }
        ladap.addAll(contactList); //no neet for else
        lv.invalidateViews();
        //lv.invalidate(); //try to call this if invalidateViews is not working, do some trial - error here
}

或者,您只需移动ladap=new ListAdapter(MainActivity.this, contactList);并将其adapter设置为onCreate

答案 1 :(得分:0)

尝试将onPostExecute方法的代码放入runOnUiThread

if (!isCancelled() && goterr == false) {
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            if(ladap==null){
                ladap=new ListAdapter(MainActivity.this, contactList);
                lv.setAdapter(ladap);
            }else{
                ladap.addAll(contactList);
            }
        }
    });
}