ArrayAdapter上的IllegalStateException

时间:2014-10-24 08:00:02

标签: android listview android-arrayadapter

我面临一个奇怪的问题。 我在listview上实现了一个自定义ArrayAdapter。 大多数时候,一切都有效。

但Crashlytics日志显示以下异常:

Fatal Exception: 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(2131034300, class android.widget.ListView) with Adapter(class com.myapp.ui.adapters.CommentsAdapter)]
android.widget.ListView.layoutChildren (ListView.java:1566)
android.widget.AbsListView.onTouchMove (AbsListView.java:4718)
android.widget.AbsListView.onTouchEvent (AbsListView.java:4582)
android.view.View.dispatchTouchEvent (View.java:8112)
android.view.ViewGroup.dispatchTransformedTouchEvent (ViewGroup.java:2414)
android.view.ViewGroup.dispatchTouchEvent (ViewGroup.java:2138)
android.view.ViewGroup.dispatchTransformedTouchEvent (ViewGroup.java:2420)
android.view.ViewGroup.dispatchTouchEvent (ViewGroup.java:2153)
android.view.ViewGroup.dispatchTransformedTouchEvent (ViewGroup.java:2420)
android.view.ViewGroup.dispatchTouchEvent (ViewGroup.java:2153)
android.view.ViewGroup.dispatchTransformedTouchEvent (ViewGroup.java:2420)
android.view.ViewGroup.dispatchTouchEvent (ViewGroup.java:2153)
android.view.ViewGroup.dispatchTransformedTouchEvent (ViewGroup.java:2420)
android.view.ViewGroup.dispatchTouchEvent (ViewGroup.java:2153)
android.view.ViewGroup.dispatchTransformedTouchEvent (ViewGroup.java:2420)
android.view.ViewGroup.dispatchTouchEvent (ViewGroup.java:2153)
android.view.ViewGroup.dispatchTransformedTouchEvent (ViewGroup.java:2420)
android.view.ViewGroup.dispatchTouchEvent (ViewGroup.java:2153)
android.view.ViewGroup.dispatchTransformedTouchEvent (ViewGroup.java:2420)
android.view.ViewGroup.dispatchTouchEvent (ViewGroup.java:2153)
com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent (PhoneWindow.java:2252)
android.app.Activity.dispatchTouchEvent (Activity.java:2507)
android.support.v7.app.ActionBarActivityDelegateICS$WindowCallbackWrapper.dispatchTouchEvent (ActionBarActivityDelegateICS.java:260)

这很奇怪,因为当您更改适配器内容而不在之后调用notifyDataSetChanged()时会发生此异常。

每次调用方法添加或清除数据时,ArrayAdapter都会调用它。

我知道当主线程没有调用notifyDatasetChanged时会发生这种崩溃,在我的情况下,它总是来自主线程。

我的适配器的主要部分:

public class CommentsAdapter extends ArrayAdapter<UserCommentShort> {

    CommentActionListener mCommentListener;
    LayoutInflater mInflater;
    final ImageLoader mImageLoader;

    private boolean mIsLoadMorePending = false;

    public CommentsAdapter(Context context, CommentActionListener commentListener) {
        super(context, 0);
        mInflater = LayoutInflater.from(context);
        mCommentListener = commentListener;
        mImageLoader = ImageLoader.getInstance();
    }

    @SuppressLint("NewApi")
    public void addAll(Collection<? extends UserCommentShort> collection, int nbComments) {
        // mNbComments = nbComments;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            addAll(collection);
        } else {
            for (final UserCommentShort userCommentShort : collection) {
                add(userCommentShort);
            }
        }
        mIsLoadMorePending = false;
    }

编辑

我对填充的调用代码(otto event bus使用@subscribe注释)。

public class CommentsFragment extends AutoRefreshFragment implements OnScrollListener {
...

    @Subscribe
    public void onDataReadyEvent(DataReadyEvent evt) {

        switch (evt.getIdApi()) {
            case DisqusThreadOperation.API_GET_DISQUS_THREAD:
            case CommunityDisqusAction.API_COMMUNITY_DISQUS_LIKE:
            case CommunityDisqusAction.API_COMMUNITY_DISQUS_DISLIKE:
            case CommunityDisqusAction.API_COMMUNITY_DISQUS_ADD_COMMENT:

                if (!TextUtils.isEmpty(mCommentsThreadIdentifier)) {
                    if (DEBUG_MODE) {
                        Log.d(TAG, "onDataReadyEvent()=" + evt);
                    }
                    final BusinessDataWithDisqusThread disqusThread = CommentsUtils.getRequiredDataEvent(evt, mCommentsThreadIdentifier);

                    if (disqusThread != null) {
                        mDisqusThreadDetails = disqusThread.getDisqusThreadDetails();
                        if (mDisqusThreadDetails != null) {
                            updateCommentDrawer(mDisqusThreadDetails.getNbPosts(), disqusThread.getDisqusThreadDetails(), disqusThread.getUserComments());
                        }
                    }
                }
                break;
        }
    }

protected void updateCommentDrawer(Integer commentCount, DisqusThreadDetails thread, UserComments userComments) {

        if (commentCount == null) {
            mTvCommentsCount.setText("");
            mListView.setVisibility(View.INVISIBLE);
            mBtnCommentsViewAll.setVisibility(View.INVISIBLE);
            mEmptyView.setVisibility(View.VISIBLE);
        } else {
            if (commentCount == 0) {
                mListView.setVisibility(View.INVISIBLE);
            } else {
                mListView.setVisibility(View.VISIBLE);
            }

            displayData(thread, userComments);

            mBtnCommentsViewAll.setVisibility(View.VISIBLE);
            mCommentsTotalCount = commentCount.intValue();

            if (mCommentsTotalCount <= 0) {
                mTvCommentsCount.setVisibility(View.GONE);
                mEmptyView.setVisibility(View.VISIBLE);
            } else {
                mTvCommentsCount.setVisibility(View.VISIBLE);
                mEmptyView.setVisibility(View.GONE);
                final String qtyComments = CommentsUtils.getCommentCountString(mCommentsTotalCount, getActivity());
                mTvCommentsCount.setText(qtyComments);
            }
        }

        refreshConnectionStatus();
    }

    protected void displayData(DisqusThreadDetails thread, UserComments userComments) {
        mAdapter.clear();
        mAdapter.addAll(userComments.getCommentList(), thread.getNbPosts());
    }

1 个答案:

答案 0 :(得分:0)

尝试修改displayData方法:

protected void displayData(DisqusThreadDetails thread, UserComments userComments) {
    runOnUiThread(new Runnable() { public void run() {
        mAdapter.clear();
        mAdapter.addAll(userComments.getCommentList(), thread.getNbPosts());
    }});
}