字符串空对象引用[重复]
Posted
技术标签:
【中文标题】字符串空对象引用[重复]【英文标题】:String null object reference [duplicate] 【发布时间】:2019-11-16 21:24:21 【问题描述】:我想在我的聊天应用程序中显示所有消息,但每次我打开活动时,应用程序都会崩溃。如果我删除 readMessage() 上的 if 方法,它会显示消息但它会在每个用户聊天中向我显示我为不同用户提供的每条消息。我不认为这是最好的解决方案。我可以修改什么? 我的数据库看起来像this
我试图断言聊天!=null。
这是我的 MessageAcitvity,我有 RecyclerView:
public class MessageActivity extends AppCompatActivity
TextView username;
FirebaseUser fuser;
DatabaseReference reference;
Intent intent;
ImageButton btn_send;
EditText text_send;
MessageAdapter messageAdapter;
List<Chat> mchat;
RecyclerView recyclerView;
@Override
protected void onCreate (Bundle savedInstanceState)
super.onCreate ( savedInstanceState );
setContentView ( R.layout.activity_message );
btn_send=findViewById ( R.id.btn_send );
text_send=findViewById ( R.id.editText );
recyclerView=findViewById ( R.id.recycler_view );
recyclerView.setHasFixedSize ( true );
LinearLayoutManager linearLayoutManager=new LinearLayoutManager ( getApplicationContext () );
linearLayoutManager.setStackFromEnd ( true );
recyclerView.setLayoutManager ( linearLayoutManager );
username=findViewById ( R.id.username6 );
intent=getIntent ();
final String userid=intent.getStringExtra ( "FIRST NAME " );
fuser= FirebaseAuth.getInstance ().getCurrentUser ();
reference= FirebaseDatabase.getInstance ().getReference ("users");
reference.addValueEventListener ( new ValueEventListener ()
@Override
public void onDataChange (@NonNull DataSnapshot dataSnapshot)
for(DataSnapshot snapshot:dataSnapshot.getChildren ())
User user=snapshot.getValue (User.class);
assert user!=null;
assert fuser!=null;
if(!fuser.getUid ().equals ( user.getFirstName () ))
username.setText ( user.getFirstName () );
readMessages ( fuser.getUid (),userid );
@Override
public void onCancelled (@NonNull DatabaseError databaseError)
);
btn_send.setOnClickListener ( new View.OnClickListener ()
@Override
public void onClick (View view)
String msg=text_send.getText ().toString ();
if(!msg.equals ( "" ))
sendMessage ( fuser.getUid (),userid,msg );
else
Toast.makeText ( MessageActivity.this,"You can't send empty",Toast.LENGTH_SHORT ).show ();
text_send.setText ( "" );
);
private void sendMessage(String sender,String receiver,String message)
DatabaseReference reference=FirebaseDatabase.getInstance ().getReference ();
HashMap<String,Object> hashMap=new HashMap<> ( );
hashMap.put ( "sender",sender );
hashMap.put ( "receiver",receiver );
hashMap.put ( "message",message );
reference.child ( "Chats" ).push ().setValue ( hashMap );
private void readMessages(final String myid, final String userid)
mchat=new ArrayList<> ( );
reference=FirebaseDatabase.getInstance ().getReference ("Chats");
reference.addValueEventListener ( new ValueEventListener ()
@Override
public void onDataChange (@NonNull DataSnapshot dataSnapshot)
mchat.clear ();
for(DataSnapshot snapshot:dataSnapshot.getChildren ())
Chat chat=snapshot.getValue (Chat.class);
assert chat != null;
if(chat.getReceiver ().equals ( myid )&& chat.getSender ().equals ( userid ) || chat.getReceiver ().equals ( userid )&& chat.getSender ().equals ( myid ))
mchat.add ( chat );
messageAdapter=new MessageAdapter ( MessageActivity.this,mchat );
recyclerView.setAdapter ( messageAdapter );
@Override
public void onCancelled (@NonNull DatabaseError databaseError)
);
我的 MessageAdapter 类:
public class MessageAdapter extends RecyclerView.Adapter<MessageAdapter.ViewHolder>
public static final int MSG_TYPE_LEFT=0;
public static final int MSH_TYPE_RIGHT=1;
private Context mContext;
private List<Chat> mChat;
FirebaseUser fuser;
public MessageAdapter(Context mContext,List<Chat> mChat)
this.mChat=mChat;
this.mContext=mContext;
@NonNull
@Override
public ViewHolder onCreateViewHolder (@NonNull ViewGroup parent, int viewType)
if(viewType==MSH_TYPE_RIGHT)
View view= LayoutInflater.from ( mContext ).inflate ( R.layout.chat_item_right ,parent,false);
return new MessageAdapter.ViewHolder ( view );
else
View view= LayoutInflater.from ( mContext ).inflate ( R.layout.chat_item_left ,parent,false);
return new MessageAdapter.ViewHolder ( view );
@Override
public void onBindViewHolder (@NonNull ViewHolder holder, int position)
Chat chat=mChat.get ( position );
holder.show_message.setText ( chat.getMessage () );
@Override
public int getItemCount ()
return mChat.size ();
public class ViewHolder extends RecyclerView.ViewHolder
public TextView show_message;
public ViewHolder(View itemView)
super(itemView);
show_message=itemView.findViewById ( R.id.show_message );
@Override
public int getItemViewType (int position)
fuser= FirebaseAuth.getInstance ().getCurrentUser ();
if(mChat.get ( position ).getSender ().equals ( fuser.getUid () ))
return MSH_TYPE_RIGHT;
else
return MSG_TYPE_LEFT;
聊天类:
public class Chat
private String sender;
private String receiver;
private String message;
public Chat (String sender, String receiver, String message)
this.sender = sender;
this.receiver = receiver;
this.message = message;
public Chat()
public String getSender ()
return sender;
public void setSender (String sender)
this.sender = sender;
public String getReceiver ()
return receiver;
public void setReceiver (String receiver)
this.receiver = receiver;
public String getMessage ()
return message;
public void setMessage (String message)
this.message = message;
调试器显示:
E/androidRuntime: FATAL EXCEPTION: main
Process: com.example.sportsbuddy, PID: 26180
java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.equals(java.lang.Object)' on a null object reference
at com.example.sportsbuddy.MessageActivity$3.onDataChange(MessageActivity.java:134)
at com.google.firebase.database.core.ValueEventRegistration.fireEvent(com.google.firebase:firebase-database@@17.0.0:75)
at com.google.firebase.database.core.view.DataEvent.fire(com.google.firebase:firebase-database@@17.0.0:63)
at com.google.firebase.database.core.view.EventRaiser$1.run(com.google.firebase:firebase-database@@17.0.0:55)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:6986)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1445)
我希望显示所有消息。
【问题讨论】:
【参考方案1】: 尝试缓存错误并在其为空时抑制它。 检查行 (.equals) 创建一个局部变量并初始化默认值(类似于 String myid=0, userid="n/a") 来自 readMessage 方法和点击监听器的问题 - 您的值是空的 记录值 DataSnapShot 并检查它【讨论】:
【参考方案2】:正如错误消息所说:
尝试在空对象引用上调用虚拟方法
boolean java.lang.String.equals(java.lang.Object)
所以你在某处打电话给something.equals(...)
,而something
是null
。堆栈跟踪告诉您问题出在:
MessageActivity$3.onDataChange(MessageActivity.java:134)
所以在 MessageActivity.java
的第 134 行,在 onDataChange
方法内。虽然我无法确定第 134 行是什么,但您共享的代码中只有一个 onDataChange
方法,并且其中只有一个对 equals
的调用:
reference.addValueEventListener ( new ValueEventListener ()
@Override
public void onDataChange (@NonNull DataSnapshot dataSnapshot)
for(DataSnapshot snapshot:dataSnapshot.getChildren ())
User user=snapshot.getValue (User.class);
assert user!=null;
assert fuser!=null;
if(!fuser.getUid ().equals ( user.getFirstName () ))
username.setText ( user.getFirstName () );
readMessages ( fuser.getUid (),userid );
所以问题似乎来自这一行:
if(!fuser.getUid().equals ( user.getFirstName () ))
具体来说:fuser.getUid()
似乎返回了null
,这意味着您正在调用null.equals(...)
,这就是错误消息的内容。
FirebaseAuth.getInstance().getCurrentUser()
返回一个用户对象,然后getUid()
返回 null 是相当罕见的,但这似乎是你正在发生的事情。
【讨论】:
问题出在 DataSnapshot 的 private void readMessages 啊,我看到确实还有另一个onDataChange
。遵循我在此处解释的相同逻辑,您将看到会发生什么。对于未来的问题,请参阅how to create a minimal, complete, verifiable example,因为现在您的问题中有不相关的代码让我走上了错误的道路(并且可能导致您收到的问题被否决)。
我尝试使用 fuser,但没有出现消息。我该怎么办?
这一行中.equals
前面的内容之一是null
: if(chat.getReceiver ().equals ( myid )&& chat.getSender ().equals ( userid ) || chat.getReceiver ().equals (userid)&& chat.getSender ().equals (myid))`。如果我的回答不能帮助您解决问题,也请查看***.com/questions/218384/…。
我发现了问题。在我的数据库中只出现了消息和发送者,而不是接收者。我认为主要的问题是在私人无效的 sendMessage 中,因为数据库中没有出现接收者。我不明白为什么它不放和接收器。以上是关于字符串空对象引用[重复]的主要内容,如果未能解决你的问题,请参考以下文章
致命异常: main ,尝试在空对象引用上调用虚拟方法 [重复]