我面临一个奇怪的问题。 我在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());
}
答案 0 :(得分:0)
尝试修改displayData
方法:
protected void displayData(DisqusThreadDetails thread, UserComments userComments) {
runOnUiThread(new Runnable() { public void run() {
mAdapter.clear();
mAdapter.addAll(userComments.getCommentList(), thread.getNbPosts());
}});
}