【发布时间】:2019-03-26 04:30:03
【问题描述】:
从 firbase 看到很多崩溃日志:
Fatal Exception: java.lang.IndexOutOfBoundsException
Invalid index 7, size is 0
java.util.ArrayList.throwIndexOutOfBoundsException (ArrayList.java:255)
java.util.ArrayList.get (ArrayList.java:308)
com.weex.app.adapters.CartoonReaderAdapter.getItemViewType (CartoonReaderAdapter.java:357)
android.widget.AbsListView$RecycleBin.getScrapView (AbsListView.java:7132)
android.widget.AbsListView.obtainView (AbsListView.java:2469)
android.widget.ListView.makeAndAddView (ListView.java:1920)
android.widget.ListView.fillUp (ListView.java:751)
android.widget.ListView.fillGap (ListView.java:690)
android.widget.AbsListView.trackMotionScroll (AbsListView.java:5579)
android.widget.AbsListView.scrollIfNeeded (AbsListView.java:3641)
android.widget.AbsListView.startScrollIfNeeded (AbsListView.java:3569)
android.widget.AbsListView.onInterceptTouchEvent (AbsListView.java:4711)
android.view.ViewGroup.dispatchTouchEvent (ViewGroup.java:2157)
似乎adapter.getItemViewType 在投掷时抛出IndexOutOfBoundsException。我检查了我的代码,所有notifyDataSetChanged 都在主线程中调用。这是我的适配器代码:
@Override
public void notifyDataSetChanged() {
Log.e("TAG","notify data change:"+Thread.currentThread().getName());
rebuildViewTypes();
super.notifyDataSetChanged();
}
@Override
public int getCount() {
return viewTypes == null ? 0 : viewTypes.size();
}
private void rebuildViewTypes() {
viewTypes.clear();
if (pictures == null || pictures.size() == 0) {
return;
}
CartoonReaderTypeItem item = null;
if (topGap > 0) {
item = new CartoonReaderTypeItem();
item.type = LIST_ITEM_TYPE_GAP;
viewTypes.add(item);
}
if (topHint != null) {
item = new CartoonReaderTypeItem();
item.type = LIST_ITEM_TYPE_TOP_HINT;
viewTypes.add(item);
}
if (pictures != null) {
for (int i = 0; i < pictures.size(); i++) {
PictureItem pictureItem = pictures.get(i);
item = new CartoonReaderTypeItem();
item.type = LIST_ITEM_TYPE_PICTURE;
item.item = pictureItem;
viewTypes.add(item);
}
}
}
@Override
public Object getItem(int position) {
CartoonReaderTypeItem item = viewTypes.get(position);
return item.item;
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public int getViewTypeCount() {
return 16;
}
/**
* @param position
* @return
*/
@Override
public int getItemViewType(int position) {
CartoonReaderTypeItem item = viewTypes.get(position);
return item.type;
}
我很困惑。所有方法(dispatchTouchEvent¬ifyDataSetChanged)都应该在主线程中调用。所以不存在线程安全问题。 viewTypes 数据可能是安全的。 IndexOutOfBoundsException 超出了我的理解范围。
有什么想法吗?
【问题讨论】:
-
看看 getCount() 和 getViewTypeCount()。有关系吗?
-
在我的适配器中,viewType 的计数不超过 16。所以 getViewTypeCount() 返回 16。
-
提供适配器的正确代码。
标签: android listadapter