问题
Hi I am trying to add a new item to my chat, I use RXJava2, to make call to my REST API to get the chat data, with this nested json response.
But I get an NullPointer when I try to add a new item to the Arraylist (Send new message):
09-08 13:35:14.529 2869-2869/com.jonathan.myapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.jonathan.myapp, PID: 2869
java.lang.NullPointerException: Attempt to invoke virtual method 'void com.jonathan.myapp.models.ChatMessageUser.setUserId(java.lang.String)' on a null object reference
at com.jonathan.myapp.ui.activity.UserChatActivity.attemptSend(UserChatActivity.java:368)
at com.jonathan.myapp.ui.activity.UserChatActivity.access$000(UserChatActivity.java:56)
at com.jonathan.myapp.ui.activity.UserChatActivity$3.onClick(UserChatActivity.java:161)
The code I use for sending the message is:
private ArrayList<ChatMessages> messageArrayList;
private void attemptSend() {
if (TextUtils.isEmpty(message)) {
mInputMessageView.requestFocus();
return;
}
mInputMessageView.setText("");
String userid = "1";
ChatMessages add = new ChatMessages();
add.setMessage(message);
add.setCreatedAt(1536407395);
add.getUser().setUserId(userid);
messageArrayList.add(add);
mAdapter.notifyDataSetChanged();
if (mAdapter.getItemCount() > 1) {
// scrolling to bottom of the recycler view
recyclerView.getLayoutManager().smoothScrollToPosition(recyclerView, null, mAdapter.getItemCount() - 1);
}
}
The Nested JSON:
{
"error": false,
"messages": [
{
"message": "hej 😀",
"message_id": 15,
"created_at": 1509383626,
"readedAt": 1536331345,
"user": {
"user_id": 2,
"username": "Lasse",
"userprofilepicture": "https://static.pexels.com/photos/305239/pexels-photo-305239.jpeg"
}
},
{
"message": "hej 😡 kar",
"message_id": 24,
"created_at": 1510411308,
"readedAt": 1511165097,
"user": {
"user_id": 1,
"username": "Jonathan",
"userprofilepicture": "https://d2lm6fxwu08ot6.cloudfront.net/img-thumbs/960w/7YWI2KZZ6N.jpg"
}
}
],
"chat_room": {
"roomId": 1,
"displayName": "Jonathan",
"displayNameImage": "https://d2lm6fxwu08ot6.cloudfront.net/img-thumbs/960w/7YWI2KZZ6N.jpg",
"createdDate": "1532032759"
}
}
My ChatThreadAdapter:
public class ChatRoomThreadAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private String userId;
private int SELF = 100;
private static String today;
private Context mContext;
private ArrayList<ChatMessages> messageArrayList;
public List<ChatMessages> getChatMessages(){
return messageArrayList;
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView message, timestamp, readedstatus;
ImageView profileimage;
public ViewHolder(View view) {
super(view);
message = (TextView) itemView.findViewById(R.id.message);
timestamp = (TextView) itemView.findViewById(R.id.timestamp);
readedstatus = (TextView) itemView.findViewById(R.id.readedstatus);
profileimage = (ImageView) itemView.findViewById(R.id.avater_image);
}
}
public ChatRoomThreadAdapter(Context mContext, ArrayList<ChatMessages> messageArrayList, String userId) {
this.mContext = mContext;
this.messageArrayList = messageArrayList;
this.userId = userId;
Calendar calendar = Calendar.getInstance();
today = String.valueOf(calendar.get(Calendar.DAY_OF_MONTH));
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView;
if (viewType == SELF) {
itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_item_message_right, parent, false);
} else {
itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_item_message_left, parent, false);
}
return new ViewHolder(itemView);
}
@Override
public int getItemViewType(int position) {
ChatMessages message = messageArrayList.get(position);
if (message.getUser().getUserId().equals(userId)) {
return SELF;
}
return position;
}
@Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {
ChatMessages message = messageArrayList.get(position);
String timestamp = TextUtils.getDateTimeStampWithTime(message.getCreatedAt());
String fimage = message.getUser().getUserprofilepicture();
String readedat = TextUtils.getDateTimeStampWithTime(message.getReadedAt());
if (message.getUser().getUserId().equals(userId)) {
// Self
((ViewHolder) holder).message.setText(Html.fromHtml(message.getMessage()));
if (message.getUser().getUsername() != null)
((ViewHolder) holder).timestamp.setText(timestamp);
((ViewHolder) holder).readedstatus.setVisibility(View.GONE);
((ViewHolder) holder).readedstatus.setVisibility(View.GONE);
} else {
// Other
((ViewHolder) holder).message.setText(Html.fromHtml(message.getMessage()));
if (message.getUser().getUsername() != null)
((ViewHolder) holder).timestamp.setText(timestamp);
if (fimage.isEmpty()) {
Picasso.with(mContext).load(R.drawable.ic_no_user)
.resize(80, 80)
.into(((ViewHolder) holder).profileimage);
} else {
Picasso.with(mContext).load(fimage)
.resize(80, 80)
.into(((ViewHolder) holder).profileimage);
}
if (message.getReadedAt().toString().equals("0")){
((ViewHolder) holder).readedstatus.setText(mContext.getResources().getString(R.string.message_delivered));
} else {
((ViewHolder) holder).readedstatus.setText(mContext.getResources().getString(R.string.message_readed_at) + " " + readedat);
}
}
}
@Override
public int getItemCount() {
return messageArrayList.size();
}
}
And my models:
public class ChatMessages {
@SerializedName("message")
@Expose
private String message;
@SerializedName("message_id")
@Expose
private Integer messageId;
@SerializedName("created_at")
@Expose
private Integer createdAt;
@SerializedName("readedAt")
@Expose
private Integer readedAt;
@SerializedName("user")
@Expose
private ChatMessageUser user;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Integer getMessageId() {
return messageId;
}
public void setMessageId(Integer messageId) {
this.messageId = messageId;
}
public Integer getCreatedAt() {
return createdAt;
}
public void setCreatedAt(Integer createdAt) {
this.createdAt = createdAt;
}
public Integer getReadedAt() {
return readedAt;
}
public void setReadedAt(Integer readedAt) {
this.readedAt = readedAt;
}
public ChatMessageUser getUser() {
return user;
}
public void setUser(ChatMessageUser user) {
this.user = user;
}
}
And the ChatMessageUser model:
public class ChatMessageUser {
@SerializedName("user_id")
@Expose
private String userId;
@SerializedName("username")
@Expose
private String username;
@SerializedName("userprofilepicture")
@Expose
private String userprofilepicture;
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getUserprofilepicture() {
return userprofilepicture;
}
public void setUserprofilepicture(String userprofilepicture) {
this.userprofilepicture = userprofilepicture;
}
}
回答1:
I think you need to initialized private ArrayList messageArrayList; you need to create new ArrayList before adding contain on this list
回答2:
When you instantiate ChatMessages object the user field in that object is null.
you must call setUser(ChatMessageUser user) method and pass an existing user object to it before calling add.getUser().setUserId(userid).
来源:https://stackoverflow.com/questions/52238177/arraylist-add-to-new-recyclerview