我将聊天功能放到我使用firebase在android studio中构建的应用程序中。我一直在遵循指南,但是,我一直收到NullPointerException错误。这是因为我从用户适配器传递的意图没有传递额外信息,甚至没有传递意图本身,所以为什么会这样?
我的代码未为我的User对象分配ID。测试应用程序时,我单击一个用户,由于未分配其ID,应用程序崩溃。
我对AS的了解不足以确切地说明为什么会这样。它似乎发生在我的用户适配器和消息传递活动中。
我根据用户列表中的位置分配了用户。
final User user = mUsers.get(position);
然后将其设置为发送到我的消息传递活动中。
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(mContext, ActualMessaging.class);
intent.putExtra("userid,", user.getId());
mContext.startActivity(intent);
}
});
一旦出现,我认为这是在我的useradapter活动中引用代码
final String userid = intent.getStringExtra("userid");
然后我尝试获取该特定的用户ID,但“用户ID”返回null。
reference = FirebaseDatabase.getInstance().getReference("Users").child(userid);
如果有人能让我知道我在做错什么,那太好了,我将在下面放置(我确定是正确的代码位)。
用户片段:
package com.example.testandroidapplication.Fragments;
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.example.testandroidapplication.Adapter.UserAdapter;
import com.example.testandroidapplication.Model.User;
import com.example.testandroidapplication.R;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import java.util.ArrayList;
import java.util.List;
public class UsersFragment extends Fragment {
private RecyclerView recyclerView;
private UserAdapter userAdapter;
private List<User> mUsers;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_users, container, false);
recyclerView = view.findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
mUsers = new ArrayList<>();
readUsers();
return view;
}
private void readUsers() {
final FirebaseUser firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Users");
reference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
mUsers.clear();
for(DataSnapshot snapshot : dataSnapshot.getChildren()){
User user = snapshot.getValue(User.class);
assert user != null;
assert firebaseUser != null;
if(!user.getId().equals(firebaseUser.getUid())){
mUsers.add(user);
}
}
userAdapter = new UserAdapter(getContext(), mUsers);
recyclerView.setAdapter(userAdapter);
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
}
}
用户适配器
package com.example.testandroidapplication.Adapter;
import android.content.Context;
import android.content.Intent;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.bumptech.glide.Glide;
import com.example.testandroidapplication.ActualMessaging;
import com.example.testandroidapplication.Model.User;
import com.example.testandroidapplication.R;
import java.util.List;
public class UserAdapter extends RecyclerView.Adapter<UserAdapter.ViewHolder> {
private Context mContext;
private List<User> mUsers;
public UserAdapter(Context mContext, List<User> mUsers){
this.mUsers = mUsers;
this.mContext = mContext;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(mContext).inflate(R.layout.user_item, parent, false);
return new UserAdapter.ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
//made user final variable, debugging, check back
final User user = mUsers.get(position);
holder.username.setText(user.getUsername());
if(user.getImageURL().equals("default")){
holder.profile_image.setImageResource(R.mipmap.ic_launcher);
} else {
Glide.with(mContext).load(user.getImageURL()).into(holder.profile_image);
}
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(mContext, ActualMessaging.class);
intent.putExtra("userid,", user.getId());
mContext.startActivity(intent);
}
});
}
@Override
public int getItemCount() {
return mUsers.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView username;
public ImageView profile_image;
public ViewHolder(View itemView) {
super(itemView);
username = itemView.findViewById(R.id.username);
profile_image = itemView.findViewById(R.id.profile_image);
}
}
}
用户类别:
package com.example.testandroidapplication.Model;
public class User {
private String id;
private String username;
private String imageURL;
public User(String id, String username, String imageURL) {
this.id = id;
this.username = username;
this.imageURL = imageURL;
}
public User(String id, String username) {
this.id = id;
this.username = username;
}
public User(String id){
this.id=id;
}
public User() {
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getImageURL() {
return imageURL;
}
public void setImageURL(String imageURL) {
this.imageURL = imageURL;
}
}
实际消息传递:
package com.example.testandroidapplication;
import android.content.Intent;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.bumptech.glide.Glide;
import com.example.testandroidapplication.Adapter.MessageAdapter;
import com.example.testandroidapplication.Model.Chat;
import com.example.testandroidapplication.Model.User;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import de.hdodenhof.circleimageview.CircleImageView;
import static com.google.android.gms.common.internal.safeparcel.SafeParcelable.NULL;
public class ActualMessaging extends AppCompatActivity {
CircleImageView profile_image;
TextView username;
FirebaseUser fuser;
DatabaseReference reference;
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_actual_messaging);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setTitle("");
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
finish();
}
});
recyclerView = findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getApplicationContext());
linearLayoutManager.setStackFromEnd(true);
recyclerView.setLayoutManager(linearLayoutManager);
profile_image = findViewById(R.id.profile_image);
username = findViewById(R.id.username);
btn_send = findViewById(R.id.btn_send);
text_send = findViewById(R.id.text_send);
Intent intent = getIntent();
final String userid = intent.getStringExtra("userid");
fuser = FirebaseAuth.getInstance().getCurrentUser();
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(ActualMessaging.this, "You can't send empty message", Toast.LENGTH_SHORT).show();
}
text_send.setText("");
}
});
fuser = FirebaseAuth.getInstance().getCurrentUser();
reference = FirebaseDatabase.getInstance().getReference("Users").child(userid);
reference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
final User user = dataSnapshot.getValue(User.class);
try {
username.setText(user.getUsername());
if (user.getImageURL().equals("default")) {
profile_image.setImageResource(R.mipmap.ic_launcher);
} else {
Glide.with(ActualMessaging.this).load(user.getImageURL()).into(profile_image);
}
readMessages(fuser.getUid(), userid, user.getImageURL());
} catch (NullPointerException npe){
Toast.makeText(ActualMessaging.this, ("userid: " + userid + "username: " + username.toString()), Toast.LENGTH_SHORT).show();
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
}
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, final String imageurl){
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);
if(chat.getReceiver().equals(myid) && chat.getSender().equals(userid) ||
chat.getReceiver().equals(userid) && chat.getSender().equals(myid)) {
mchat.add(chat);
}
messageAdapter = new MessageAdapter(ActualMessaging.this, mchat, imageurl);
recyclerView.setAdapter(messageAdapter);
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
}
}
Logcat错误
2019-03-11 22:36:47.920 18284-18284/com.example.testandroidapplication E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.testandroidapplication, PID: 18284
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.testandroidapplication/com.example.testandroidapplication.ActualMessaging}: java.lang.NullPointerException: Can't pass null for argument 'pathString' in child()
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2913)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
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:858)
Caused by: java.lang.NullPointerException: Can't pass null for argument 'pathString' in child()
at com.google.firebase.database.DatabaseReference.child(com.google.firebase:firebase-database@@16.1.0:101)
at com.example.testandroidapplication.ActualMessaging.onCreate(ActualMessaging.java:109)
at android.app.Activity.performCreate(Activity.java:7136)
at android.app.Activity.performCreate(Activity.java:7127)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2893)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
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:858)
谢谢您的建议。
答案 0 :(得分:0)
问题:此行使您的应用无法按预期运行。
intent.putExtra("userid,", user.getId());
如您所见,您必须使用 userid 而不是 userid ,并以逗号结尾。
解决方案::将代码更改为
intent.putExtra("userid", user.getId());
答案 1 :(得分:0)
您要在putExtra中添加“用户ID” ,并获取“用户ID” 。
所以它变成了错误。
更新代码,并在用户适配器中使用此行
intent.putExtra("userid", user.getId());
,您还可以通过此代码访问userid
intent.putExtra("userid", mUsers.get(position).getId());
希望这对您有帮助!
谢谢。
答案 2 :(得分:0)
我认为您可以先检查userid是否为null,然后仅应传递child() 在您的情况下,问题在于您传递的密钥是不同的,并且获取也不同,因此需要获取正确的密钥。 如果您要传递密钥
intent.putExtra("userid,", user.getId());
获取密钥
String userid = intent.getStringExtra("userid,");
或 您还可以将密钥创建为常量
public static final USERID="userid"
intent.putExtra(USERID, user.getId());
获取密钥
String userid = intent.getStringExtra(USERID);
这不会造成拼写错误