Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Recycler View Fatal Exception: java.lang.ArrayIndexOutOfBoundsException

I have got this stack trace though crashlytics. I have no idea where the issue is.

Is there any alternative of StaggeredGridLayoutManager that I can use to get a listview like layout.

Fatal Exception: java.lang.ArrayIndexOutOfBoundsException: start < 0 || end > len. start=-1, end=11, len=11
   at java.util.Arrays.checkStartAndEnd(Arrays.java:1745)
   at java.util.Arrays.fill(Arrays.java:803)
   at android.support.v7.widget.StaggeredGridLayoutManager$LazySpanLookup.invalidateAfter(SourceFile:2404)
   at android.support.v7.widget.StaggeredGridLayoutManager.handleUpdate(SourceFile:1373)
   at android.support.v7.widget.StaggeredGridLayoutManager.onItemsRemoved(SourceFile:1327)
   at android.support.v7.widget.RecyclerView$6.dispatchUpdate(SourceFile:725)
   at android.support.v7.widget.RecyclerView$6.onDispatchFirstPass(SourceFile:716)
   at android.support.v7.widget.AdapterHelper.dispatchFirstPassAndUpdateViewHolders(SourceFile:316)
   at android.support.v7.widget.AdapterHelper.dispatchAndUpdateViewHolders(SourceFile:302)
   at android.support.v7.widget.AdapterHelper.applyRemove(SourceFile:182)
   at android.support.v7.widget.AdapterHelper.preProcess(SourceFile:103)
   at android.support.v7.widget.RecyclerView.processAdapterUpdatesAndSetAnimationFlags(SourceFile:2767)
   at android.support.v7.widget.RecyclerView.onMeasure(SourceFile:2538)
   at android.view.View.measure(View.java:16521)
   at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5134)
   at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1404)
   at android.widget.LinearLayout.measureVertical(LinearLayout.java:695)
   at android.widget.LinearLayout.onMeasure(LinearLayout.java:588)
   at android.view.View.measure(View.java:16521)
   at android.support.v4.view.ViewPager.onMeasure(SourceFile:1489)
   at android.view.View.measure(View.java:16521)
   at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:719)
   at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:455)
   at android.view.View.measure(View.java:16521)
   at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:719)
   at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:455)
   at android.view.View.measure(View.java:16521)
   at android.support.v4.widget.DrawerLayout.onMeasure(SourceFile:940)
   at android.view.View.measure(View.java:16521)
   at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5134)
   at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
   at android.support.v7.widget.ContentFrameLayout.onMeasure(SourceFile:135)
   at android.view.View.measure(View.java:16521)
   at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5134)
   at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
   at android.view.View.measure(View.java:16521)
   at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5134)
   at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
   at android.view.View.measure(View.java:16521)
   at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5134)
   at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1404)
   at android.widget.LinearLayout.measureVertical(LinearLayout.java:695)
   at android.widget.LinearLayout.onMeasure(LinearLayout.java:588)
   at android.view.View.measure(View.java:16521)
   at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5134)
   at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
   at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2331)
   at android.view.View.measure(View.java:16521)
   at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:1925)
   at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1117)
   at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1299)
   at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1004)
   at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5739)
   at android.view.Choreographer$CallbackRecord.run(Choreographer.java:761)
   at android.view.Choreographer.doCallbacks(Choreographer.java:574)
   at android.view.Choreographer.doFrame(Choreographer.java:544)
   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:5380)
   at java.lang.reflect.Method.invokeNative(Method.java)
   at java.lang.reflect.Method.invoke(Method.java:515)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:970)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:786)
   at dalvik.system.NativeStart.main(NativeStart.java)

This is what I am doing to handle click listeners in one of the adapter

     @Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
  holder.relative.setClickable(true);

    holder.relative.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            if (itemClickListener != null)
                itemClickListener.onClick(v, position);
            else
                AppConfig.log("itemClickLestener was null");
        }
    });

    holder.relative.setOnLongClickListener(new View.OnLongClickListener() {
        @Override
        public boolean onLongClick(View v) {
            if (itemClickListener != null)
                itemClickListener.onLongClick(v, position);
            return true;
        }
    });
  return view;
  }
like image 799
Rajnish Mishra Avatar asked Feb 23 '16 12:02

Rajnish Mishra


People also ask

What causes Java Lang ArrayIndexOutOfBoundsException?

The ArrayIndexOutOfBoundsException is one of the most common errors in Java. It occurs when a program attempts to access an invalid index in an array i.e. an index that is less than 0, or equal to or greater than the length of the array.

What is a Java ArrayIndexOutOfBoundsException?

ArrayIndexOutOfBoundsException occurs when we access an array, or a Collection, that is backed by an array with an invalid index. This means that the index is either less than zero or greater than or equal to the size of the array.

What is arrayindexoutofboundsexception in Java?

The java.lang.ArrayIndexOutOfBoundsException is one of the most common exceptions in java. It occurs when the programmer tries to access the value of an element in an array at an invalid index. This Exception is introduced in Java from JDK Version 1.0 onwards.

What is arrayoutofboundsexception in for loop?

Once the for loop is iterated, it considers the condition I <=veggies.length, which means that the array considers the elements from 0 th position until the 6 th position and finally, during the last iteration, the value i=6 exceeds the array size, and therefore, the ArrayoutOfBoundsException is implemented.

How do you get arrayoutofboundsexception for negative index?

Accessing ArrayOutOfBoundsException for negative index Here, we first declare an array of integers, and then we look into accessing the individual elements in the array. Once that is done, we try to print out the first element by giving the command intArray [0]. This recognizes the 0 th element, which is 5 and hence prints it.


2 Answers

Looks like you were trying to call getAdapterPosition() while Recycler View layouts are not calculated (possibly triggered by a notifyDataSetChanged() call).

always handle it like this

final int position = getAdapterPosition();
if(positon != RecyclerView.NO_POSITION){
    // you can trust the adapter position
    // do whatever you intend to do with this position
}

The documentation clearly states the following

if you want to access the item in the adapter on a ViewHolder click, you should use getAdapterPosition(). Beware that these methods may not be able to calculate adapter positions if notifyDataSetChanged() has been called and new layout has not yet been calculated. For this reasons, you should carefully handle NO_POSITION or null results from these methods.

UPDATE

Now that you have finally posted some code. here are some things you should consider.

  1. Do not pass final parameters inside onBindViewHolder. By the time the OnClickListener is fired the position is not guaranteed to be the same as you think it would be. So do this

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        holder.relative.setClickable(true);
        //do other stuff
    }
    
  2. DO NOT assign any listeners inside onBindViewHolder method. As the view gets recycled you end up setting listeners multiple times to the same view. Instead, set it inside the view holder class or onCreateViewHolder method like below

    @Override
    public MyViewHolder onCreateViewHolder (ViewGroup parent, int viewType) {
        View myView = LayoutInflater.from(parent.getContext())
                            .inflate(R.layout.my_layout, parent, false);
    
        //setting listeners on creation
        myView.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                final int position = getAdapterPosition();
                if(position != RecyclerView.NO_POSITION){
                    //do whatever you want with the clicked position
                }
            }
        });
    
       //return the view holder
       return new MyViewHolder(myView);
    }
    

    Or in the ViewHolder class

    public class MyViewHolder extends RecyclerView.ViewHolder {
    
         public MyViewHolder(View itemView) {
             super(itemView);
    
             //setting listeners inside viewHolder class
             itemView.setOnClickListener(new View.OnClickListener(){
                 @Override
                 public void onClick(View v) {
                    final int position = getAdapterPosition();
                    if(position != RecyclerView.NO_POSITION){
                        //do whatever you want with the clicked position
                    }
                 }
              });
            }
       }
    

Fixing the above may fix your problem. I highly recommend you to check the Google Dev Summit 2015 video about RecyclerView. It is really interesting and they talk about the ins and outs of the RecyclerView. They also mention why not to pass final parameters inside onBinViewHolder. Click here to check out the exact moment in the video in which they talk about it.

like image 123
Much Overflow Avatar answered Oct 07 '22 20:10

Much Overflow


Mostly this error will be occuring in your on bindview where you will be using the data of your arraylist. Make sure you have used position -1 value of the arraylist.

like image 36
Vaibhav Sharma Avatar answered Oct 07 '22 20:10

Vaibhav Sharma