Categories
discuss

Inconclusive Error with No reference or Unable to find Reference causing – java.lang.IndexOutOfBoundsException

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.

Categories
discuss

How can I get console.log output from my mobile ON the mobile device?

I do a lot of my dev work from mobile devices. Is there a way to get js access to console.log output from within a mobile browser?

Answer

Currently, the best method would be to ‘hook into’ the native console and display the output as HTML, while still allowing the output to go to the native console.

You could implement your own version very easily….

// Reference to an output container, use 'pre' styling for JSON output
var output = document.createElement('pre');
document.body.appendChild(output);

// Reference to native method(s)
var oldLog = console.log;

console.log = function( ...items ) {

    // Call native method first
    oldLog.apply(this,items);

    // Use JSON to transform objects, all others display normally
    items.forEach( (item,i)=>{
        items[i] = (typeof item === 'object' ? JSON.stringify(item,null,4) : item);
    });
    output.innerHTML += items.join(' ') + '<br />';

};

// You could even allow Javascript input...
function consoleInput( data ) {
    // Print it to console as typed
    console.log( data + '<br />' );
    try {
        console.log( eval( data ) );
    } catch (e) {
        console.log( e.stack );
    }
}

….but rather than reinvent the wheel, there’s a couple projects you might be interested in trying.

I’m personally using hnlDesign’s mobileConsole and have been very happy with it. It’s simple and just what you’d want and expect.

I recently became aware of Eruda but haven’t had a chance to test it, other than playing with their demo. It implements a lot more developer tools, but for this reason might also be overkill for a lot of projects. It doesn’t feel as lightweight (its file size is definitely much larger, even minified!), and if you want the breadth and intensity of developer tools, it would be better to use remote debugging. Most of us who are wanting a mobile console are just wanting the basics for quick tests and the like.

Categories
discuss

Font is not applying on CheckBox and Switch Android Studio 3

After updating to Android Studio 3 and using the latest SDK and build tools there is a feature to add fonts to the fonts folder under resources and use it directly in xml or java. I’m using this code in my theme in styles.xml to apply theme on my whole application

<item name="android:fontFamily">@font/iransansfont</item>

it’s working on Button, TextView, and pretty much everything except CheckBox and Switch widgets. I even tried fontFamily on my CheckBoxs and Switchs but it’s not working either. How can i fix it?

Answer

Currently it is not possible to set fonts on CheckBoxes (and some other widgets) with font resources via XML. You can do it programmatically instead:

checkBox.setTypeface(ResourcesCompat.getFont(context, R.font.your_font));

This issue has been reported on the Android bug tracker, star it to get it fixed soon: https://issuetracker.google.com/issues/63250768

Categories
discuss

Angular 4 – “Expression has changed after it was checked” error while using NG-IF

I setup a service to keep track of logged in users. That service returns an Observable and all components that subscribe to it are notified (so far only a single component subscribe to it).

Service:

private subject = new Subject<any>();

sendMessage(message: boolean) {
   this.subject.next( message );
}

getMessage(): Observable<any> {
   return this.subject.asObservable();
} 

Root App Component: (this component subscribes to the observable)

ngAfterViewInit(){
   this.subscription = this._authService.getMessage().subscribe(message => { this.user = message; });
}

Welcome Component:

ngOnInit() {
  const checkStatus = this._authService.checkUserStatus();
  this._authService.sendMessage(checkStatus);
}

App Component Html: (this is where the error occurs)

<div *ngIf="user"><div>

What I’m trying to do:

I want every component (except the Root App Component) to send the users logged-in state to the Root App Component so I can manipulate the UI within the Root App Component Html.

The issue:

I get the following error when the Welcome Component is initialised.

Expression has changed after it was checked. Previous value: 'undefined'. Current value: 'true'.

Please note this error occurs on this *ngIf="user" expression which is located within Root App Components HTML file.

Can someone explain the reason for this error and how I can fix this?

On a side note: If you think theres a better way to achieve what I’m trying to do then please let me know.

Update 1:

Putting the following in the constructor solves the issue but don’t want to use the constructor for this purpose so it seems it’s not a good solution.

Welcome Component:

constructor(private _authService: AuthenticationService) {
  const checkStatus = this._authService.checkUserStatus();
  this._authService.sendMessage(checkStatus);
 }

Root App Component:

constructor(private _authService: AuthenticationService){
   this.subscription = this._authService.getMessage().subscribe(message => { this.usr = message; });
}

Update 2:

Here’s the plunkr. To see the error check the browser console. When the app loads a boolean value of true should be displayed but I get the error in the console.

Please note that this plunkr is a very basic version of my main app. As the app is bit large I couldn’t upload all the code. But the plunkr demonstrates the error perfectly.

Answer

What this means is that the change detection cycle itself seems to have caused a change, which may have been accidental (ie the change detection cycle caused it somehow) or intentional. If you do change something in a change detection cycle on purpose, then this should retrigger a new round of change detection, which is not happening here. This error will be suppressed in prod mode, but means you have issues in your code and cause mysterious issues.

In this case, the specific issue is that you’re changing something in a child’s change detection cycle which affects the parent, and this will not retrigger the parent’s change detection even though asynchronous triggers like observables usually do. The reason it doesn’t retrigger the parent’s cycle is becasue this violates unidirectional data flow, and could create a situation where a child retriggers a parent change detection cycle, which then retriggers the child, and then the parent again and so on, and causes an infinite change detection loop in your app.

It might sound like I’m saying that a child can’t send messages to a parent component, but this is not the case, the issue is that a child can’t send a message to a parent during a change detection cycle (such as life cycle hooks), it needs to happen outside, as in in response to a user event.

The best solution here is to stop violating unidirectional data flow by creating a new component that is not a parent of the component causing the update so that an infinite change detection loop cannot be created. This is demonstrated in the plunkr below.

New app.component with child added:

<div class="col-sm-8 col-sm-offset-2">
      <app-message></app-message>
      <router-outlet></router-outlet>
</div>

message component:

@Component({
  moduleId: module.id,
  selector: 'app-message',
  templateUrl: 'message.component.html'
})
export class MessageComponent implements OnInit {
   message$: Observable<any>;
   constructor(private messageService: MessageService) {

   }

   ngOnInit(){
      this.message$ = this.messageService.message$;
   }
}

template:

<div *ngIf="message$ | async as message" class="alert alert-success">{{message}}</div>

slightly modified message service (just a slightly cleaner structure):

@Injectable()
export class MessageService {
    private subject = new Subject<any>();
    message$: Observable<any> = this.subject.asObservable();

    sendMessage(message: string) {
       console.log('send message');
        this.subject.next(message);
    }

    clearMessage() {
       this.subject.next();
    }
}

This has more benefits than just letting change detection work properly with no risk of creating infinite loops. It also makes your code more modular and isolates responsibility better.

https://plnkr.co/edit/4Th7m0Liovfgd1Z3ECWh?p=preview

Categories
discuss

Merge two arrays with alternating values

I would like to merge 2 arrays with a different length:

let array1 = ["a", "b", "c", "d"];
let array2 = [1, 2];

The outcome I would expect is ["a", 1 ,"b", 2, "c", "d"]

What’s the best way to do that?

Answer

You could iterate the min length of both array and build alternate elements and at the end push the rest.

var array1 = ["a", "b", "c", "d"],
    array2 = [1, 2],
    result = [],
    i, l = Math.min(array1.length, array2.length);
    
for (i = 0; i < l; i++) {
    result.push(array1[i], array2[i]);
}
result.push(...array1.slice(l), ...array2.slice(l));

console.log(result);

Solution for an arbitrary count of arrays with a transposing algorithm and later flattening.

var array1 = ["a", "b", "c", "d"],
    array2 = [1, 2],
    result = [array1, array2]
        .reduce((r, a) => (a.forEach((a, i) => (r[i] = r[i] || []).push(a)), r), [])
        .reduce((a, b) => a.concat(b));
    
console.log(result);
Source: stackoverflow
Text is available under the Creative Commons Attribution-ShareAlike License; additional terms may apply. By using this site, you agree to the Privacy Policy, and Copyright Policy. Content is available under CC BY-SA 3.0 unless otherwise noted. The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 © No Copyrights, All Questions are retrived from public domain..