4

I get a following error in my crash list and i have not idea on how to link it with my code, as it looks generic and inconclusive

java.lang.IndexOutOfBoundsException: 

  at java.util.ArrayList.throwIndexOutOfBoundsException (ArrayList.java:255)

  at java.util.ArrayList.get (ArrayList.java:308)

  at android.widget.ArrayAdapter.getItem (ArrayAdapter.java:337)

  at android.widget.ArrayAdapter.createViewFromResource (ArrayAdapter.java:390)

  at android.widget.ArrayAdapter.getView (ArrayAdapter.java:362)

  at android.widget.Spinner.makeView (Spinner.java:661)

  at android.widget.Spinner.layout (Spinner.java:609)

  at android.widget.Spinner.onLayout (Spinner.java:568)

  at android.view.View.layout (View.java:16075)

  at android.view.ViewGroup.layout (ViewGroup.java:5300)

  at android.widget.LinearLayout.setChildFrame (LinearLayout.java:1703)

  at android.widget.LinearLayout.layoutHorizontal (LinearLayout.java:1692)

  at android.widget.LinearLayout.onLayout (LinearLayout.java:1468)

  at android.view.View.layout (View.java:16075)

  at android.view.ViewGroup.layout (ViewGroup.java:5300)

  at android.widget.LinearLayout.setChildFrame (LinearLayout.java:1703)

  at android.widget.LinearLayout.layoutVertical (LinearLayout.java:1557)

  at android.widget.LinearLayout.onLayout (LinearLayout.java:1466)

  at android.view.View.layout (View.java:16075)

  at android.view.ViewGroup.layout (ViewGroup.java:5300)

  at android.widget.FrameLayout.layoutChildren (FrameLayout.java:579)

  at android.widget.FrameLayout.onLayout (FrameLayout.java:514)

  at android.widget.ScrollView.onLayout (ScrollView.java:1511)

  at android.view.View.layout (View.java:16075)

  at android.view.ViewGroup.layout (ViewGroup.java:5300)

  at android.support.v4.view.ViewPager.onLayout (ViewPager.java:1795)

  at android.view.View.layout (View.java:16075)

  at android.view.ViewGroup.layout (ViewGroup.java:5300)

  at android.widget.RelativeLayout.onLayout (RelativeLayout.java:1077)

  at android.view.View.layout (View.java:16075)

  at android.view.ViewGroup.layout (ViewGroup.java:5300)

  at android.widget.LinearLayout.setChildFrame (LinearLayout.java:1703)

  at android.widget.LinearLayout.layoutVertical (LinearLayout.java:1557)

  at android.widget.LinearLayout.onLayout (LinearLayout.java:1466)

  at android.view.View.layout (View.java:16075)

  at android.view.ViewGroup.layout (ViewGroup.java:5300)

  at android.widget.FrameLayout.layoutChildren (FrameLayout.java:579)

  at android.widget.FrameLayout.onLayout (FrameLayout.java:514)

  at android.view.View.layout (View.java:16075)

  at android.view.ViewGroup.layout (ViewGroup.java:5300)

  at android.widget.LinearLayout.setChildFrame (LinearLayout.java:1703)

  at android.widget.LinearLayout.layoutVertical (LinearLayout.java:1557)

  at android.widget.LinearLayout.onLayout (LinearLayout.java:1466)

  at android.view.View.layout (View.java:16075)

  at android.view.ViewGroup.layout (ViewGroup.java:5300)

  at android.widget.FrameLayout.layoutChildren (FrameLayout.java:579)

  at android.widget.FrameLayout.onLayout (FrameLayout.java:514)

  at android.view.View.layout (View.java:16075)

  at android.view.ViewGroup.layout (ViewGroup.java:5300)

  at android.widget.LinearLayout.setChildFrame (LinearLayout.java:1703)

  at android.widget.LinearLayout.layoutVertical (LinearLayout.java:1557)

  at android.widget.LinearLayout.onLayout (LinearLayout.java:1466)

  at android.view.View.layout (View.java:16075)

  at android.view.ViewGroup.layout (ViewGroup.java:5300)

  at android.widget.FrameLayout.layoutChildren (FrameLayout.java:579)

  at android.widget.FrameLayout.onLayout (FrameLayout.java:514)

  at android.view.View.layout (View.java:16075)

  at android.view.ViewGroup.layout (ViewGroup.java:5300)

  at android.view.ViewRootImpl.performLayout (ViewRootImpl.java:2119)

  at android.view.ViewRootImpl.performTraversals (ViewRootImpl.java:1873)

  at android.view.ViewRootImpl.doTraversal (ViewRootImpl.java:1073)

  at android.view.ViewRootImpl$TraversalRunnable.run (ViewRootImpl.java:5988)

  at android.view.Choreographer$CallbackRecord.run (Choreographer.java:767)

  at android.view.Choreographer.doCallbacks (Choreographer.java:580)

  at android.view.Choreographer.doFrame (Choreographer.java:550)

  at android.view.Choreographer$FrameDisplayEventReceiver.run (Choreographer.java:753)

  at android.os.Handler.handleCallback (Handler.java:739)

  at android.os.Handler.dispatchMessage (Handler.java:95)

  at android.os.Looper.loop (Looper.java:135)

  at android.app.ActivityThread.main (ActivityThread.java:5930)

  at java.lang.reflect.Method.invoke (Native Method)

  at java.lang.reflect.Method.invoke (Method.java:372)

  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:1405)

  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1200)

I am new to android programming, any help on how to fix this issue is greatly appreciated.

Becos everyone is asking the adapter code i will post One sample adapter here,

public class ChatAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    public static final int REP_TYPE = 1;
    public static final int ME_TYPE = 2;
    public static final int FILE_TYPE = 4;
    public static final int FILE_DONE = 5;
    public static final int FILE_DONE_REP = 6;
    public static final int FOOTER_TYPE = 3;

    List<Message> messages;
    String rep_photo;
    String me_photo;

    Context context;

    public ChatAdapter(Context context) {
        this.context = context;
        messages = new ArrayList<>();
    }

    public ChatAdapter(Context context, String rep_photo, String me_photo) {
        messages = new ArrayList<>();
        this.rep_photo = rep_photo;
        this.me_photo = me_photo;
        this.context = context;
    }

    public void setMessages(List<Message> messageList){
        messages = messageList;
        notifyDataSetChanged();
    }

    public void addMessage(Message message){
        messages.add(0, message);
        notifyItemInserted(0);
    }

    public void addMessageList(List<Message> messageList){
        int size = this.messages.size();
        this.messages.remove(size -1);
        notifyItemRemoved(size - 1);
        size = this.messages.size();
        this.messages.addAll(messageList);
        notifyItemRangeInserted(size, messageList.size());
    }

    public void replaceFileMessage(){
        int position = 0;
        for (Message message1 : messages){
            if (message1.msg.contains("::FILE::")){
                position = messages.indexOf(message1);
                messages.remove(position);
                break;
            }
        }
        notifyItemRemoved(position);
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        switch (viewType){
            case FILE_TYPE: return new FileHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_me_chat_file, parent, false));
            case FILE_DONE: return new FileDoneHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_me_chat_file_done, parent, false));
            case FILE_DONE_REP: return new FileDoneRepHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_rep_chat_file_done, parent, false));
            case FOOTER_TYPE: return new FooterHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.footer_user_list, parent, false));
            case ME_TYPE: return new MeHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_me_msg, parent, false));
            default: return new RepHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_rep_message, parent, false));
        }
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        Message message = messages.get(position);
        if (holder instanceof MeHolder){
            MeHolder meHolder = (MeHolder) holder;
            meHolder.bind(message);
        }else if (holder instanceof RepHolder){
            RepHolder repHolder = (RepHolder) holder;
            repHolder.bind(message);
        }else if (holder instanceof FileHolder){
            FileHolder fileHolder = (FileHolder) holder;
            fileHolder.bind(message);
        }else if (holder instanceof FileDoneHolder){
            FileDoneHolder fileDoneHolder = (FileDoneHolder) holder;
            fileDoneHolder.bind(message);
        }else if (holder instanceof FileDoneRepHolder){
            FileDoneRepHolder fileDoneRepHolder = (FileDoneRepHolder) holder;
            fileDoneRepHolder.bind(message);
        }
    }

    @Override
    public int getItemViewType(int position) {
        if (messages.size() > 0 && messages.size() > 25 &&
                position == messages.size() - 1 && messages.get(position) == null){
            return FOOTER_TYPE;
        }else {
            Message message = messages.get(position);
            if (message.from_user.equals(AppSetting.getInstance().getUserData().user_id) && message.msg.contains("::FILE::")) {
                return FILE_TYPE;
            }else if (message.from_user.equals(AppSetting.getInstance().getUserData().user_id) && message.msg.contains("::FILE_DONE::")) {
                return FILE_DONE;
            }else if (message.to_user.equals(AppSetting.getInstance().getUserData().user_id) && message.msg.contains("::FILE_DONE::")) {
                return FILE_DONE_REP;
            }else if(message.from_user.equals(AppSetting.getInstance().getUserData().user_id)){
                return ME_TYPE;
            } else {
                return REP_TYPE;
            }
        }
    }

    @Override
    public int getItemCount() {
        return messages.size();
    }

    class RepHolder extends RecyclerView.ViewHolder implements Html.ImageGetter{

        @BindView(R.id.ivUser)
        CircleImageView ivUser;

        @BindView(R.id.tvMsg)
        BlackTextView tvMsg;

        @BindView(R.id.tvTime)
        BlackTextView tvTime;

        public RepHolder(View itemView) {
            super(itemView);
            ButterKnife.bind(this, itemView);
        }

        public void bind(final Message message){
            for(String s : ChatActivity.smilesMapReplaces.keySet()){
                if (message.msg.contains(s)){
                    String img = "<img src='" + s + "' />";
                    if (s.equals(":)")){
                        s = ":\\)";
                    }else if(s.equals(":(")){
                        s = ":\\(";
                    }else if(s.equals(";)")){
                        s = ";\\)";
                    }
                    message.msg = message.msg.replaceAll(s, img);
                }
            }
            tvMsg.setText(Html.fromHtml(message.msg, this, null));
            Picasso.with(ivUser.getContext()).load(rep_photo).into(ivUser);
            tvTime.setText(DateUtils.getDisplayTime(tvTime.getContext(), message.created, DateUtils.DATE_FORMAT_ISO_8601));
            ivUser.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    ((BaseActivity)ivUser.getContext()).startActivity(ProfileActivity.class, AppSetting.getInstance().getUserData().user_id.equals(message.from_user) ? message.to_user : message.from_user, false);
                }
            });
            if (message.msg.startsWith("http")){
                tvMsg.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(message.msg));
                        tvMsg.getContext().startActivity(browserIntent);
                    }
                });
            }
        }

        @Override
        public Drawable getDrawable(String source) {
            if (source.contains("http")) {
                LevelListDrawable d = new LevelListDrawable();
                Drawable empty = tvMsg.getContext().getResources().getDrawable(R.drawable.logo);
                d.addLevel(0, 0, empty);
                d.setBounds(0, 0, empty.getIntrinsicWidth(), empty.getIntrinsicHeight());

                new LoadImage().execute(source, d);

                return d;
            }else{
                int id = ChatActivity.smilesMapReplaces.get(source);
                Drawable d = tvMsg.getContext().getResources().getDrawable(id);
                d.setBounds(0,0,d.getIntrinsicWidth() * 3/2,d.getIntrinsicHeight() * 3/2);
                return d;
            }
        }

        class LoadImage extends AsyncTask<Object, Void, Bitmap> {

            private LevelListDrawable mDrawable;

            @Override
            protected Bitmap doInBackground(Object... params) {
                String source = (String) params[0];
                mDrawable = (LevelListDrawable) params[1];
                try {
                    InputStream is = new URL(source).openStream();
                    return BitmapFactory.decodeStream(is);
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                return null;
            }

            @Override
            protected void onPostExecute(Bitmap bitmap) {
                if (bitmap != null) {
                    BitmapDrawable d = new BitmapDrawable(bitmap);
                    mDrawable.addLevel(1, 1, d);
                    mDrawable.setBounds(0, 0, bitmap.getWidth()*3, bitmap.getHeight()*3);
                    mDrawable.setLevel(1);
                    // i don't know yet a better way to refresh TextView
                    // mTv.invalidate() doesn't work as expected
                    CharSequence t = tvMsg.getText();
                    tvMsg.setText(t);
                }
            }
        }
    }

    class FileHolder extends RecyclerView.ViewHolder{

        @BindView(R.id.tvName)
        BlackTextView tvName;

        @BindView(R.id.tvTime)
        BlackTextView tvTime;

        @BindView(R.id.ivUser)
        ImageView ivUser;

        public FileHolder(View itemView) {
            super(itemView);
            ButterKnife.bind(this, itemView);
        }

        public void bind(Message message){
            String fileName = message.msg.substring(8, message.msg.length());
            tvName.setText(fileName);
            Picasso.with(ivUser.getContext()).load(me_photo).into(ivUser);
            tvTime.setText(DateUtils.getDisplayTime(tvTime.getContext(), message.created, DateUtils.DATE_FORMAT_ISO_8601));
        }
    }

    class FileDoneHolder extends RecyclerView.ViewHolder{

        @BindView(R.id.tvName)
        BlackTextView tvName;

        @BindView(R.id.tvTime)
        BlackTextView tvTime;

        @BindView(R.id.ivUser)
        ImageView ivUser;

        @BindView(R.id.ivFile)
        ImageView ivFile;

        @BindView(R.id.ivAttachment)
        ImageView ivAttachment;

        public FileDoneHolder(View itemView) {
            super(itemView);
            ButterKnife.bind(this, itemView);
        }

        public void bind(Message message){
            final String fileName = message.msg.substring(13, message.msg.length());
            tvName.setText(fileName);
            Picasso.with(ivUser.getContext()).load(me_photo).into(ivUser);
            tvTime.setText(DateUtils.getDisplayTime(tvTime.getContext(), message.created, DateUtils.DATE_FORMAT_ISO_8601));
            tvName.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    File fileDir = new File(Environment.getExternalStorageDirectory().toString() + "/araliya/");
                    if (!fileDir.exists()){
                        fileDir.mkdir();
                    }
                    File file = new File(Environment.getExternalStorageDirectory().toString() + "/araliya/" + fileName);
                    if (file.exists()){
                        UIUtils.openFile(context, file.getAbsolutePath());
                    }else{
                        new DownloadFileFromURL(fileName).execute(Constants.BASE_FILE_URL + fileName);
                    }
                }
            });
            ivAttachment.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    File fileDir = new File(Environment.getExternalStorageDirectory().toString() + "/araliya/");
                    if (!fileDir.exists()){
                        fileDir.mkdir();
                    }
                    File file = new File(Environment.getExternalStorageDirectory().toString() + "/araliya/" + fileName);
                    if (file.exists()){
                        UIUtils.openFile(context, file.getAbsolutePath());
                    }else{
                        new DownloadFileFromURL(fileName).execute(Constants.BASE_FILE_URL + fileName);
                    }
                }
            });
        }
    }

    class FileDoneRepHolder extends RecyclerView.ViewHolder{

        @BindView(R.id.tvName)
        BlackTextView tvName;

        @BindView(R.id.tvTime)
        BlackTextView tvTime;

        @BindView(R.id.ivUser)
        ImageView ivUser;

        @BindView(R.id.ivAttachment)
        ImageView ivAttachment;

        public FileDoneRepHolder(View itemView) {
            super(itemView);
            ButterKnife.bind(this, itemView);
        }

        public void bind(Message message){
            final String fileName = message.msg.substring(13, message.msg.length());
            tvName.setText(fileName);
            Picasso.with(ivUser.getContext()).load(rep_photo).into(ivUser);
            tvTime.setText(DateUtils.getDisplayTime(tvTime.getContext(), message.created, DateUtils.DATE_FORMAT_ISO_8601));
            ivAttachment.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    File fileDir = new File(Environment.getExternalStorageDirectory().toString() + "/araliya/");
                    if (!fileDir.exists()){
                        fileDir.mkdir();
                    }
                    File file = new File(Environment.getExternalStorageDirectory().toString() + "/araliya/" + fileName);
                    if (file.exists()){
                        UIUtils.openFile(context, file.getAbsolutePath());
                    }else{
                        new DownloadFileFromURL(fileName).execute(Constants.BASE_FILE_URL + fileName);
                    }
                }
            });
            tvName.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    File fileDir = new File(Environment.getExternalStorageDirectory().toString() + "/araliya/");
                    if (!fileDir.exists()){
                        fileDir.mkdir();
                    }
                    File file = new File(Environment.getExternalStorageDirectory().toString() + "/araliya/" + fileName);
                    if (file.exists()){
                        UIUtils.openFile(context, file.getAbsolutePath());
                    }else{
                        new DownloadFileFromURL(fileName).execute(Constants.BASE_FILE_URL + fileName);
                    }
                }
            });
        }
    }

    class MeHolder extends RecyclerView.ViewHolder implements Html.ImageGetter{
        @BindView(R.id.ivUser)
        CircleImageView ivUser;

        @BindView(R.id.tvMsg)
        BlackTextView tvMsg;

        @BindView(R.id.tvTime)
        BlackTextView tvTime;

        public MeHolder(View itemView) {
            super(itemView);
            ButterKnife.bind(this, itemView);
        }

        public void bind(final Message message){
            for(String s : ChatActivity.smilesMapReplaces.keySet()){

                if (message.msg.contains(s)){
                    String img = "<img src='" + s + "' />";
                    if (s.equals(":)")){
                        s = ":\\)";
                    }else if(s.equals(":(")){
                        s = ":\\(";
                    }else if(s.equals(";)")){
                        s = ";\\)";
                    }
                    message.msg = message.msg.replaceAll(s, img);
                }
            }
            tvMsg.setText(Html.fromHtml(message.msg, this, null));
            Picasso.with(ivUser.getContext()).load(me_photo).into(ivUser);
            ivUser.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    ((BaseActivity)ivUser.getContext()).startActivity(ProfileActivity.class, AppSetting.getInstance().getUserData().user_id, false);
                }
            });
            if (message.msg.startsWith("http")){
                tvMsg.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(message.msg));
                        tvMsg.getContext().startActivity(browserIntent);
                    }
                });
            }
            tvTime.setText(DateUtils.getDisplayTime(tvTime.getContext(), message.created, DateUtils.DATE_FORMAT_ISO_8601));
        }

        @Override
        public Drawable getDrawable(String source) {
            if (source.contains("http")) {
                LevelListDrawable d = new LevelListDrawable();
                Drawable empty = tvMsg.getContext().getResources().getDrawable(R.drawable.logo);
                d.addLevel(0, 0, empty);
                d.setBounds(0, 0, empty.getIntrinsicWidth(), empty.getIntrinsicHeight());

                new LoadImage().execute(source, d);

                return d;
            }else{
                int id = ChatActivity.smilesMapReplaces.get(source);
                Drawable d = tvMsg.getContext().getResources().getDrawable(id);
                d.setBounds(0,0,d.getIntrinsicWidth() * 3/2,d.getIntrinsicHeight() * 3/2);
                return d;
            }
        }

        class LoadImage extends AsyncTask<Object, Void, Bitmap> {

            private LevelListDrawable mDrawable;

            @Override
            protected Bitmap doInBackground(Object... params) {
                String source = (String) params[0];
                mDrawable = (LevelListDrawable) params[1];
                try {
                    InputStream is = new URL(source).openStream();
                    return BitmapFactory.decodeStream(is);
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                return null;
            }

            @Override
            protected void onPostExecute(Bitmap bitmap) {
                if (bitmap != null) {
                    BitmapDrawable d = new BitmapDrawable(bitmap);
                    mDrawable.addLevel(1, 1, d);
                    mDrawable.setBounds(0, 0, bitmap.getWidth()*3, bitmap.getHeight()*3);
                    mDrawable.setLevel(1);
                    // i don't know yet a better way to refresh TextView
                    // mTv.invalidate() doesn't work as expected
                    CharSequence t = tvMsg.getText();
                    tvMsg.setText(t);
                }
            }
        }
    }

    class FooterHolder extends RecyclerView.ViewHolder{

        public FooterHolder(View itemView) {
            super(itemView);
        }
    }

    class DownloadFileFromURL extends AsyncTask<String, String, String> {

        String fileName;
        public DownloadFileFromURL(String fileName) {
            this.fileName = fileName;
        }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
        }

        @Override
        protected String doInBackground(String... f_url) {
            int count;
            try {
                URL url = new URL(f_url[0]);
                URLConnection conection = url.openConnection();
                conection.connect();

                // this will be useful so that you can show a tipical 0-100%
                // progress bar
                int lenghtOfFile = conection.getContentLength();

                // download the file
                InputStream input = new BufferedInputStream(url.openStream(),
                        8192);

                // Output stream
                OutputStream output = new FileOutputStream(Environment
                        .getExternalStorageDirectory().toString()
                        + "/araliya/" + fileName);

                byte data[] = new byte[1024];

                long total = 0;

                while ((count = input.read(data)) != -1) {
                    total += count;
                    // publishing the progress....
                    // After this onProgressUpdate will be called
                    publishProgress("" + (int) ((total * 100) / lenghtOfFile));

                    // writing data to file
                    output.write(data, 0, count);
                }

                // flushing output
                output.flush();

                // closing streams
                output.close();
                input.close();

            } catch (Exception e) {
                Log.e("Error: ", e.getMessage());
                e.printStackTrace();
                return  null;
            }

            return fileName;
        }

        protected void onProgressUpdate(String... progress) {
        }

        @Override
        protected void onPostExecute(String file_url) {
            if (file_url != null){
                UIUtils.openFile(context, Environment.getExternalStorageDirectory().toString() + "/araliya/" + file_url);
            }
        }

    }

}
mahen3d
  • 7,047
  • 13
  • 51
  • 103
  • Best guess is that you've modified the `List` backing your `Adapter` without calling `notifyDataSetChanged()`, so the adapter thinks it has more items than it actually does. Could you post all adapter-related code you have? – Ben P. Nov 01 '17 at 23:21
  • @BenP. There is about 30+ adapters in use throughout the project how am i suppose to know where it is calling this. – mahen3d Nov 02 '17 at 02:21
  • You really need to post your code. Without it, we really can't help much. – BlackHatSamurai Nov 04 '17 at 05:00
  • @BlackHatSamurai as i said really impossible to test and post 50+ adapter code used in the app, as i dont even know which area it crashes. – mahen3d Nov 04 '17 at 06:30
  • Without the code it's impossible to help you. But the stacktrace very clearly says that the index out of bounds exception happens in `ArrayList.java` class on line 255 – BlackHatSamurai Nov 04 '17 at 22:39
  • You are showing an RecyerView.Adapter, but your error is at some ArrayAdapter, you need to find the one – Marcos Vasconcelos Nov 07 '17 at 18:07
  • 1
    Debug your code or add logging, so you know what adapter was executing with what data. – Wesley De Keirsmaeker Nov 10 '17 at 16:23
  • @WesleyDeKeirsmaeker as i said really impossible to test and post 50+ adapter code used in the app, as i dont even know which area it crashes – mahen3d Nov 10 '17 at 23:35

3 Answers3

6

java.lang.IndexOutOfBoundsException: at java.util.ArrayList.throwIndexOutOfBoundsException (ArrayList.java:255)

IndexOutOfBoundsException is an unchecked exception that extends RuntimeException .

REASON

This exception can be thrown to indicate an attempt to access an index which is out of bounds on objects like String, Array, or Vector. Usually any negative integer less than or equal to -1 and positive integer greater than or equal to the size of the object is an index which would be out of bounds.

Handling

The process of handling the exception thrown by the Java Runtime Environment, while the program is being executed, is known as exception handling. use try-catch() block.

try  
    {
      // Your CODE

    }
    catch(IndexOutOfBoundsException  exp)  // Exception
    {
      System.out.println("Exception "  + exp.getMessage() );
    }

If I can't find-out when this breaks it's really impossible to debug as i have large app with over 50+ adapters calling in different different actions.

It will be better if you Debugging App. It's a good practice.

WHY ?

Debugging allows you to go through each line of code, methods and how well your code is working. It’s easier to find small mistake in large pieces of code.

Coming from

 @Override
    public int getItemViewType(int position) {
        if (messages.size() > 0 && messages.size() > 25 &&
                position == messages.size() - 1 && messages.get(position) == null){
            return FOOTER_TYPE;
        }

Debug if section. Check every conditions properly satisfied or not. Specially messages.size().

IntelliJ Amiya
  • 74,896
  • 15
  • 165
  • 198
  • I understand this needs a try catch block however my question is more of how to find what action it causes this exception because there is over 1000+ active users and only 1 person is having this issue, plus all the adapters and testing seems to be fine, i think there is one particular rare case which causes this issue, however its impossible to replicate this error or debug as you guys saying its not just a simple app with simple logic. – mahen3d Nov 04 '17 at 12:46
  • @mahen3d I understand your problem. It will be helpful if you share your code. App DEBUGGING is the best approach to find problem as far as i know. – IntelliJ Amiya Nov 04 '17 at 15:33
  • @mahen3d You can visit https://stackoverflow.com/a/21570366/3395198 and https://stackoverflow.com/questions/32014513/java-util-arraylist-throwindexoutofboundsexceptionarraylist-java255-error – IntelliJ Amiya Nov 04 '17 at 15:34
4

According to this exception:

java.lang.IndexOutOfBoundsException:
at java.util.ArrayList.throwIndexOutOfBoundsException (ArrayList.java:255)
at java.util.ArrayList.get (ArrayList.java:308)

and this method:

@Override
public int getItemViewType(int position) {
    if (messages.size() > 0 && messages.size() > 25 &&
        position == messages.size() - 1 && messages.get(position) == null){
        return FOOTER_TYPE;
    }else {
        Message message = messages.get(position);
        if (message.from_user.equals(AppSetting.getInstance().getUserData().user_id) && message.msg.contains("::FILE::")) {
            return FILE_TYPE;
        }else if (message.from_user.equals(AppSetting.getInstance().getUserData().user_id) && message.msg.contains("::FILE_DONE::")) {
            return FILE_DONE;
        }else if (message.to_user.equals(AppSetting.getInstance().getUserData().user_id) && message.msg.contains("::FILE_DONE::")) {
            return FILE_DONE_REP;
        }else if(message.from_user.equals(AppSetting.getInstance().getUserData().user_id)){
            return ME_TYPE;
        } else {
            return REP_TYPE;
        }
    }
}

I think that the following lines might be the cause of the problem:

if (messages.size() > 0 && messages.size() > 25 && position == messages.size() - 1 && messages.get(position) == null) {...}
else {
    Message message = messages.get(position);
    ...
}

When you do: messages.get(position) it throws IndexOutOfBoundsException if the index is out of range. So, what do you think will happen if position is 29 but messages.size() is 27? And any idea regarding this check messages.size() > 0 && messages.size() > 25 in your if block? I think that you should focus on messages list and position value. To avoid exception on messages.get(position) operation the value of position should follow this rule: -1 < position < messages.size().

Additional Info:

From android documentation, method int getItemViewType(int position):

Get the type of View that will be created by getView(int, View, ViewGroup) for the specified item.

Parameter: position - int: The position of the item within the adapter's data set whose view type we want.

Returns - An integer representing the type of View. Two views should share the same type if one can be converted to the other in getView(int, View, ViewGroup). Note: Integers must be in the range 0 to getViewTypeCount() - 1. IGNORE_ITEM_VIEW_TYPE can also be returned.

So, the reason is that position of the item within the adapter's data set does not correspond to the position of item in List<Message> messages.

Community
  • 1
  • 1
Ibrokhim Kholmatov
  • 1,079
  • 2
  • 13
  • 16
  • 1
    This answer is wrong and misleading! The ``Message message = messages.get(position);`` cannot be the reason, because if it were the reason it then would be listed in the stacktrace. The suggested code change at the end is also wrong. Method ``notifyItemRangeInserted()`` expects the number of inserted items as second argument. The original code is correct. See https://developer.android.com/reference/android/support/v7/widget/RecyclerView.Adapter.html#notifyItemRangeInserted(int,%20int) – Boomer Nov 10 '17 at 19:44
  • @Boomer thanks for your response! Agree with notifyItemRangeInserted(), it's my fault, edited, sorry for that. – Ibrokhim Kholmatov Nov 10 '17 at 20:41
2

I think that is due to out of memory. Sometimes android create unknown error like this when there is OOM error. It must be for user with low memory remaining on device.

Profile your app. Android 3.0 introduce great feature for profiling app, so use that.

Find memory leaks Finding memory leak can help you to build bug free applications. Even if you know your app is good with memory management, you should cgeck for it.

Manage memory Find out some memory management tips for android and use it.

**Best practices ** Try googling for best practices for android development. This will help you lot to solve your problem.

Lalit Jadav
  • 1,409
  • 1
  • 15
  • 38