Не удается отобразить ответ JSON при первом переходе на страницу в приложении Android - PullRequest
0 голосов
/ 07 августа 2020

Я сейчас создаю приложение для чата. Проблема, с которой я столкнулся, заключается в том, что, когда я впервые вхожу в действие / страницу чата, я не смогу увидеть ответ на мой вызов запроса JSON (в виде Recycler View). Результат будет виден только в том случае, если я нажму кнопку «Назад», а затем снова открою то же действие в чате. Это означает, что мой ответ опаздывает на мой жизненный цикл 1 (или аналогичный).

На мой взгляд, я ожидал, что журнал чата появится с первой попытки, когда я открою чат.

Я пытался найти похожие вопросы в Stack Overflow, но ни один из них не связан с моими проблемами и не решил их. Я также попытался переместить свой код для выполнения в другом жизненном цикле Android (например, сделать запрос onCreate и показать результат onResume или в почтовом резюме), но ошибка все еще не решена.

EDIT: Я запросил мои пользовательские сообщения после щелчка по контакту и сохранение его в объекте Intent через putExtra (). Итак, если есть сообщения из предыдущего чата, их следует сохранить в Intent и передать, когда я перейду к MessageActivity. java. Кроме того, я добавил свой contactRecylerViewAdapter. java код

Вот изображение того, как выглядит проблема: Первая попытка

first attempt

After refresh

введите описание изображения здесь

Вот код моей активности:

MessageActivity. java

public class MessageActivity extends AppCompatActivity {

    Toolbar chatToolBar;

    RecyclerView recyclerView;

    TextView nickname;

    ImageView profileImage;

    EditText edit_message;

    ImageButton sendButton;


    private MessageAdapter messageAdapter = new MessageAdapter();

    Intent intent;

    int CURRENT_USER_ID = LoginActivity.USER_ID;

    int CONTACT_ID;
    String CONTACT_NICKNAME;
    int CONTACT_IMG;
    int ROOM_ID;


    ArrayList<Message> msg;

    String BASE_URL = URL.BASE_URL;
    RequestQueue queue;


    @Override
    protected void onResume() {
        super.onResume();
        messageAdapter.setMessage(MessageActivity.this,msg);
        recyclerView.setAdapter(messageAdapter);
    }


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_message);

        queue = Volley.newRequestQueue(getApplicationContext());
        initialize();

//        System.out.println(getLifecycle().getCurrentState() + " It is here");



        sendButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                updateBackend();
                msg.add(new Message(CURRENT_USER_ID,ROOM_ID,edit_message.getText().toString()));
                edit_message.setText("");
                messageAdapter.setMessage(MessageActivity.this,msg);
                recyclerView.setAdapter(messageAdapter);
            }
        });
    }

    private void updateBackend() {
        String url = BASE_URL +"add-message/";
        StringRequest stringRequest = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
               showMessages();
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Toast.makeText(MessageActivity.this, "Failed to send message", Toast.LENGTH_SHORT).show();
            }
        }) {
            @Override
            protected Map<String, String> getParams() throws AuthFailureError {
                Map<String,String> params = new HashMap<>();
                params.put("room",Integer.toString(ROOM_ID));
                params.put("sender_user",Integer.toString(CURRENT_USER_ID));
                params.put("receiver_user",Integer.toString(CONTACT_ID));
                params.put("message",edit_message.getText().toString());
                return params;
            }
        };
        queue.add(stringRequest);
    }

    private void showMessages() {
        String url = BASE_URL + "get-message/" + ROOM_ID +"/";
        StringRequest stringRequest =  new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                msg.clear();
                try {
                    JSONArray jsonArray =  new JSONArray(response);
                    for(int i = 0; i < jsonArray.length(); i++){
                        JSONObject jsonObject = jsonArray.getJSONObject(i);
                        msg.add(new Message(jsonObject.getInt("sender_user"),ROOM_ID,jsonObject.getString("message")));
                    }
                    messageAdapter.setMessage(MessageActivity.this,msg);
                    recyclerView.setAdapter(messageAdapter);
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Toast.makeText(MessageActivity.this, "Failed to show messages", Toast.LENGTH_SHORT).show();
            }
        });
        queue.add(stringRequest);

    }

    private void initialize() {

        chatToolBar = findViewById(R.id.toolbar);

        setSupportActionBar(chatToolBar);
        getSupportActionBar().setTitle("");
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        chatToolBar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });


//        ActionBar actionBar = getSupportActionBar();
//        actionBar.setDefaultDisplayHomeAsUpEnabled(true);
//        actionBar.setDisplayShowCustomEnabled(true);

//        LayoutInflater layoutInflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
//        View actionBarView = layoutInflater.inflate(R.layout.toolbar,null);
//        actionBar.setCustomView(actionBarView);


        recyclerView = findViewById(R.id.message_rec_view);
        recyclerView.setHasFixedSize(true);
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getApplicationContext());
        linearLayoutManager.setStackFromEnd(true);
        recyclerView.setLayoutManager(linearLayoutManager);

        nickname = findViewById(R.id.username);
        profileImage = findViewById(R.id.custom_profile_image);
        sendButton = findViewById(R.id.send_button);
        edit_message = findViewById(R.id.text_send);


        intent = getIntent();
        CONTACT_ID = intent.getIntExtra("contactId", -1);
        CONTACT_NICKNAME = intent.getStringExtra("contactNickname");
        CONTACT_IMG = intent.getIntExtra("contactImage", R.drawable.defaultpic);
        ROOM_ID = intent.getIntExtra("roomID", -1);
        msg = intent.getParcelableArrayListExtra("messages");

        nickname.setText(CONTACT_NICKNAME);
        profileImage.setImageResource(CONTACT_IMG);



    }
}

MessageAdapter. java

public class MessageAdapter extends RecyclerView.Adapter<MessageAdapter.MessageViewHolder> {

    final static int MSG_TYPE_LEFT = 1;
    final static int MSG_TYPE_RIGHT = 2;
    ArrayList<Message> messageList;

    private Context mContext;

    public MessageAdapter(){
    }

    @NonNull
    @Override
    public MessageViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        if(viewType == MSG_TYPE_RIGHT) {
            View view = LayoutInflater.from(mContext).inflate(R.layout.outgoing_chat,parent,false);
            return new MessageAdapter.MessageViewHolder(view);
        } else {
            View view = LayoutInflater.from(mContext).inflate(R.layout.incoming_chat,parent,false);
            return new MessageAdapter.MessageViewHolder(view);
        }
    }

    @Override
    public void onBindViewHolder(@NonNull final MessageViewHolder holder, final int position) {
        Message message = messageList.get(position);
        holder.show_message.setText(message.getMessage());

        //Remember to set up for profile pic
    }

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

    @Override
    public int getItemViewType(int position) {
        if(messageList.get(position).getSenderID() == LoginActivity.USER_ID) {
            return MSG_TYPE_RIGHT;
        } else {
            return MSG_TYPE_LEFT;
        }
    }

    public void setMessage(Context mContext, ArrayList<Message> messageList) {
        this.mContext = mContext;
        this.messageList =messageList;
        notifyDataSetChanged();
    }

    class MessageViewHolder extends RecyclerView.ViewHolder{
        public TextView show_message;
        public CircleImageView profile_image;

        MessageViewHolder(View itemview){
            super(itemview);
            profile_image = itemview.findViewById(R.id.profile_image);
            show_message = itemview.findViewById(R.id.show_message_current_user);
        }
    }
}

contactRecViewAdapter. java

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

    ArrayList<ContactModel> contacts = new ArrayList<>();
    ArrayList<Message> msg = new ArrayList<>();

    Context mContext;

    String BASE_URL = URL.BASE_URL;
    int CURRENT_USER_ID = LoginActivity.USER_ID;
    int PRIVATE_CHAT = 1;

    int ROOM_ID;

    RequestQueue queue;
    public contactRecViewAdapter() {}


    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
       View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.contacts_list,parent,false);
       return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull final ViewHolder holder, final int position) {
        queue = Volley.newRequestQueue(mContext);

        holder.contact_name.setText(contacts.get(position).getContact_name());
        holder.contact_profile_image.setImageResource(contacts.get(position).getImage());

        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                checkRoomCreated(position);


                Intent intent = new Intent(mContext,MessageActivity.class);
                intent.putExtra("contactId",contacts.get(position).getContact_id());
                intent.putExtra("contactNickname",contacts.get(position).getContact_name());
                intent.putExtra("contactImage",contacts.get(position).getImage());
                intent.putExtra("roomID",ROOM_ID);
                intent.putParcelableArrayListExtra("messages",msg);

                mContext.startActivity(intent);
            }
        });
    }


    private void checkRoomCreated(final int position) {
        String url = BASE_URL +"find-room/" + CURRENT_USER_ID + "/"  +contacts.get(position).getContact_id()+ "/";
        StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                try {
                    JSONArray jsonArray = new JSONArray(response);
                    if(jsonArray.isNull(0)) {
                        createRoom(position);
                    } else {
                        JSONObject jsonObject =  jsonArray.getJSONObject(0);
                        ROOM_ID = jsonObject.getInt("room");
                        getMessage();
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Toast.makeText(mContext, "Request to find room failed!!", Toast.LENGTH_SHORT).show();
            }
        });
        queue.add(stringRequest);
    }

    private void getMessage() {
        String url = BASE_URL + "get-message/" + ROOM_ID +"/";
        StringRequest stringRequest =  new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                msg.clear();
                try {
                    JSONArray jsonArray =  new JSONArray(response);
                    for(int i = 0; i < jsonArray.length(); i++){
                        JSONObject jsonObject = jsonArray.getJSONObject(i);
                        msg.add(new Message(jsonObject.getInt("sender_user"),ROOM_ID,jsonObject.getString("message")));
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Toast.makeText(mContext, "Failed to show messages", Toast.LENGTH_SHORT).show();
            }
        });
        queue.add(stringRequest);
    }

    private void createParticipants(int position) {
        String url = BASE_URL +"participants/";
        ArrayList<Integer> idList = new ArrayList<>();
        idList.add(CURRENT_USER_ID);
        idList.add(contacts.get(position).getContact_id());
        for(final int id :idList) {
            StringRequest stringRequest = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
                @Override
                public void onResponse(String response) {
                    System.out.println("User " +id  + " added to participants");
                }
            }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    Toast.makeText(mContext, "Try to create new participants but failed", Toast.LENGTH_SHORT).show();
                }
            }) {
                @Override
                protected Map<String, String> getParams() throws AuthFailureError {
                    Map<String, String> params = new HashMap<>();
                    params.put("room", Integer.toString(ROOM_ID));
                    params.put("user", Integer.toString(id));
                    return params;
                }
            };
            queue.add(stringRequest);
        }
    }

    private void createRoom(final int position) {
        String url = BASE_URL +"room/";
        StringRequest stringRequest =  new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                try {
                    JSONObject jsonObject = new JSONObject(response);
                    ROOM_ID = jsonObject.getInt("id");
                    createParticipants(position);
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Toast.makeText(mContext, "Try to create room but error", Toast.LENGTH_SHORT).show();
            }
        }){
            @Override
            protected Map<String, String> getParams() throws AuthFailureError {
                Map<String,String> params =  new HashMap<>();
                params.put("name",CURRENT_USER_ID + " and " + contacts.get(position).getContact_id());
                params.put("type",Integer.toString(PRIVATE_CHAT));
                return params;
            }
        };
        queue.add(stringRequest);
    }

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

    public void setContacts(ArrayList<ContactModel> contacts, Context mContext) {
        this.contacts = contacts;
        this.mContext = mContext;
        notifyDataSetChanged();
    }


    public class ViewHolder extends RecyclerView.ViewHolder{
        private TextView contact_name;
        private ImageView contact_profile_image;


        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            contact_name = itemView.findViewById(R.id.contact_name);
            contact_profile_image = itemView.findViewById(R.id.contact_profile_image);
        }
    }
}
...