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); } } } }
Answer
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
.