填充RecyclerView当ArrayIndexOutOfBoundsException异常 [英] ArrayIndexOutOfBoundsException when populating RecyclerView
问题描述
我得到一个错误,每隔一段时间当我尝试填充我RecyclerView但错误似乎在内部发生的 StaggeredGridLayoutManager
。
我填充从我的数据库中的RecyclerView然后使用这个图像添加到我的适配器
列表< WImage>图像;公共无效addImages(LinkedHashMap的<整数,WImage> newImages){
对于(Map.Entry的<整数,WImage>项:newImages.entrySet()){
addImage(entry.getValue(),entry.getKey());
}
}公共无效addImage(WImage形象,诠释位置){
images.add(位置,图像);
notifyItemRangeInserted(位置,1);}
什么是奇怪的是,当应用程序第一次加载它是好的,正确地显示一切,但如果我有一组不同的基于数据库查询图像替换一下目前正处于RecyclerView然后用初始图像再次,我得到回来这个错误。
java.lang.ArrayIndexOutOfBoundsException:src.length = 16 srcPos = 0 dst.length = 0 dstPos = 0长度= 16
在java.lang.System.arraycopy(本机方法)
在android.support.v7.widget.StaggeredGridLayoutManager$LazySpanLookup.ensureSize(StaggeredGridLayoutManager.java:2277)
在android.support.v7.widget.StaggeredGridLayoutManager$LazySpanLookup.offsetForAddition(StaggeredGridLayoutManager.java:2323)
在android.support.v7.widget.StaggeredGridLayoutManager.handleUpdate(StaggeredGridLayoutManager.java:1280)
在android.support.v7.widget.StaggeredGridLayoutManager.onItemsAdded(StaggeredGridLayoutManager.java:1253)
在android.support.v7.widget.RecyclerView $ 5.dispatchUpdate(RecyclerView.java:406)
在android.support.v7.widget.RecyclerView $ 5.onDispatchSecondPass(RecyclerView.java:422)
在android.support.v7.widget.AdapterHelper.consumePostponedUpdates(AdapterHelper.java:119)
在android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:1896)
在android.support.v7.widget.RecyclerView.resumeRequestLayout(RecyclerView.java:1101)
在android.support.v7.widget.RecyclerView $ 1.run(RecyclerView.java:155)
在android.view.Choreographer $ CallbackRecord.run(Choreographer.java:761)
在android.view.Choreographer.doCallbacks(Choreographer.java:574)
在android.view.Choreographer.doFrame(Choreographer.java:543)
在android.view.Choreographer $ FrameDisplayEventReceiver.run(Choreographer.java:747)
在android.os.Handler.handleCallback(Handler.java:733)
在android.os.Handler.dispatchMessage(Handler.java:95)
在android.os.Looper.loop(Looper.java:136)
在android.app.ActivityThread.main(ActivityThread.java:5086)
在java.lang.reflect.Method.invokeNative(本机方法)
在java.lang.reflect.Method.invoke(Method.java:515)
在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:785)
在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
在dalvik.system.NativeStart.main(本机方法)
它遍历所有图片就好了,但是当它准备打电话 onBindViewHolder
再次崩溃。
当我更改RecyclerView数据我从查询中使用新的数据填充之前删除一切先用这种
公共无效的removeAll(){
images.clear();
notifyDataSetChanged();
}
我也试过将它们插入全部一次,然后调用 notifyItemRangeInserted
的起始位置和图像的总数目,但它仍然具有相同的错误crashsed。
修改
这似乎发生时,我打20左右的项目,我需要投入电网。如果我只是用 notifyDatasetChanged
它似乎工作正常,但我想用 notifyItemRangeInserted
,所以我得到了很好的插入动画
有其他人看到这个问题?
EDIT2
这是我的 onCreateViewHolder
@覆盖
公共ViewHolder onCreateViewHolder(ViewGroup中ViewGroup中,最终int i)以{ 视图V = LayoutInflater.from(viewGroup.getContext())膨胀(R.layout.image_normal_grid_cell,ViewGroup中,假的)。
返回新ViewHolder(V);
}
和我的 onBindViewHolder
@覆盖
公共无效onBindViewHolder(最终ViewHolder持有人,最终int i)以{
最终WImage图像= images.get(I)
holder.v.setOnClickListener(新View.OnClickListener(){
@覆盖
公共无效的onClick(视图v){
listener.onItemClick(V,I,图像);
}
}); holder.heart.setActivated(image.getLikeDislike()); holder.heart.setOnClickListener(新View.OnClickListener(){
@覆盖
公共无效的onClick(视图v){
Uri.Builder UB = SyncProvider.CONTENT_ID_URI_BASE.buildUpon();
ub.appendPath(将String.valueOf(image.getId()));
ContentValues值=新ContentValues(); 如果(image.getLikeDislike()){
values.put(SyncProvider.LIKE,0);
holder.heart.setActivated(假);
image.setLikeDislike(假);
}其他{
values.put(SyncProvider.LIKE,1);
holder.heart.setActivated(真);
image.setLikeDislike(真);
}
values.put(SyncProvider.IMAGE_CHANGED,1);
context.getContentResolver()更新(ub.build(),价值观,NULL,NULL);
}
});
如果(cancelPotentialDownload(image.getUri(),holder.imageview)){
LoadImageTask任务=新LoadImageTask(holder.imageview,image.getThumbUri());
holder.imageview.setImageDrawable(新AsyncBitmap(任务));
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
}
编辑3
在这里,当我更换适配器我做什么
在我的抽屉里资产净值选定的指数变化我初始化我的装载机进行查询
公共无效initLoader(INT页){
如果(当前是=页面和放大器;!&安培;!mAdapter = NULL){
mAdapter.removeAll();
hashImages.clear();
。getLoaderManager()destroyLoader(当前页);
}
当前页=页;
。getLoaderManager()initLoader(页,空,这一点);
}
然后在我的onLoadFinished我的装载机我的对象添加到适配器
@覆盖
公共无效onLoadFinished(装载机<&光标GT; cursorLoader,光标光标){
如果(光标=空&放大器;!&放大器; cursor.moveToFirst()){
做{
WImage形象=新WImage(光标);
如果(!hashImages.containsKey(image.getId())){
newImages.put(tempHash.size(),图像);
}否则如果(image.getImageChanged()){
更新= TRUE;
}
INT POS = tempHash.size();
tempHash.put(image.getId(),POS)
}而(cursor.moveToNext());
} 如果(newImages.size()大于0){
mAdapter.addImages(newImages);
}
我觉得这个问题是由的 HTTPS://$c$c.google.com/p/android/issues/detail ID = 77846 ?
您可以替换 notifyDataSetChanged
调用特定事件通知( notifyItemRemoved /添加
),看看是否可以重现吗?
I am getting an error every so often when I try to populate my RecyclerView but the error seems to happening internally in the StaggeredGridLayoutManager
.
I populate the RecyclerView from my database then add the images to my adapter using this
List<WImage> images;
public void addImages(LinkedHashMap<Integer,WImage> newImages){
for(Map.Entry<Integer,WImage> entry : newImages.entrySet()){
addImage(entry.getValue(),entry.getKey());
}
}
public void addImage(WImage image, int position){
images.add(position,image);
notifyItemRangeInserted(position, 1);
}
What is weird is when the app first loads it is fine and displays everything correctly but if I replace what was currently in the RecyclerView with a different set of images based on a database query then come back with the initial images again I get this error.
java.lang.ArrayIndexOutOfBoundsException: src.length=16 srcPos=0 dst.length=0 dstPos=0 length=16
at java.lang.System.arraycopy(Native Method)
at android.support.v7.widget.StaggeredGridLayoutManager$LazySpanLookup.ensureSize(StaggeredGridLayoutManager.java:2277)
at android.support.v7.widget.StaggeredGridLayoutManager$LazySpanLookup.offsetForAddition(StaggeredGridLayoutManager.java:2323)
at android.support.v7.widget.StaggeredGridLayoutManager.handleUpdate(StaggeredGridLayoutManager.java:1280)
at android.support.v7.widget.StaggeredGridLayoutManager.onItemsAdded(StaggeredGridLayoutManager.java:1253)
at android.support.v7.widget.RecyclerView$5.dispatchUpdate(RecyclerView.java:406)
at android.support.v7.widget.RecyclerView$5.onDispatchSecondPass(RecyclerView.java:422)
at android.support.v7.widget.AdapterHelper.consumePostponedUpdates(AdapterHelper.java:119)
at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:1896)
at android.support.v7.widget.RecyclerView.resumeRequestLayout(RecyclerView.java:1101)
at android.support.v7.widget.RecyclerView$1.run(RecyclerView.java:155)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:761)
at android.view.Choreographer.doCallbacks(Choreographer.java:574)
at android.view.Choreographer.doFrame(Choreographer.java:543)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:747)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5086)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
at dalvik.system.NativeStart.main(Native Method)
it goes through all the images just fine but when its ready to call onBindViewHolder
again it crashes.
When I change the data in the RecyclerView I remove everything first with this before populating with the new data from the query
public void removeAll(){
images.clear();
notifyDataSetChanged();
}
I also tried inserting them all at once and then calling notifyItemRangeInserted
with the start position and the total number of images but it still crashsed with the same error.
EDIT
it seems to happen when I hit about 20 or so items that I need to put into the Grid. If I just use notifyDatasetChanged
it seems to work fine but I want to use notifyItemRangeInserted
so I get the nice insert animation
Has anyone else seen this problem?
EDIT2
here is my onCreateViewHolder
@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, final int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.image_normal_grid_cell, viewGroup, false);
return new ViewHolder(v);
}
and my onBindViewHolder
@Override
public void onBindViewHolder(final ViewHolder holder, final int i) {
final WImage image = images.get(i);
holder.v.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
listener.onItemClick(v,i,image);
}
});
holder.heart.setActivated(image.getLikeDislike());
holder.heart.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Uri.Builder ub = SyncProvider.CONTENT_ID_URI_BASE.buildUpon();
ub.appendPath(String.valueOf(image.getId()));
ContentValues values = new ContentValues();
if(image.getLikeDislike()){
values.put(SyncProvider.LIKE,0);
holder.heart.setActivated(false);
image.setLikeDislike(false);
}else{
values.put(SyncProvider.LIKE,1);
holder.heart.setActivated(true);
image.setLikeDislike(true);
}
values.put(SyncProvider.IMAGE_CHANGED,1);
context.getContentResolver().update(ub.build(),values,null,null);
}
});
if(cancelPotentialDownload(image.getUri(),holder.imageview)){
LoadImageTask task = new LoadImageTask(holder.imageview,image.getThumbUri());
holder.imageview.setImageDrawable(new AsyncBitmap(task));
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
}
EDIT 3
here is what I do when I replace the adapter
on selected index change of my nav drawer I init my loader to make a query
public void initLoader(int page){
if(currentPage != page && mAdapter != null){
mAdapter.removeAll();
hashImages.clear();
getLoaderManager().destroyLoader(currentPage);
}
currentPage = page;
getLoaderManager().initLoader(page,null,this);
}
then in my onLoadFinished of my loader I add the objects to the adapter
@Override
public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor) {
if(cursor != null && cursor.moveToFirst()){
do{
WImage image = new WImage(cursor);
if(!hashImages.containsKey(image.getId())){
newImages.put(tempHash.size(),image);
}else if(image.getImageChanged()){
update = true;
}
int pos = tempHash.size();
tempHash.put(image.getId(),pos);
}while(cursor.moveToNext());
}
if(newImages.size() > 0){
mAdapter.addImages(newImages);
}
I think this problem is triggered by https://code.google.com/p/android/issues/detail?id=77846.
Can you replace notifyDataSetChanged
calls with specific notify events (notifyItemRemoved/Added
) and see if you can reproduce it?
这篇关于填充RecyclerView当ArrayIndexOutOfBoundsException异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!