在我的应用程序中,我使用此 ConnectionInformation.java
为每个用户存储数据列表。
package trickandroid.fulllogin;
/**
* Created by Simon Peter on 19-May-17.
*/
public class ConnectionInformation {
String due, selectArea, connectionNum, doorNum, conName, phoneNum, aadharNum, rationNum;
public ConnectionInformation(){
}
public ConnectionInformation(String due, String selectArea, String connectionNum, String doorNum, String conName, String phoneNum, String aadharNum, String rationNum) {
this.connectionNum = connectionNum;
this.doorNum = doorNum;
this.conName = conName;
this.phoneNum = phoneNum;
this.aadharNum = aadharNum;
this.rationNum = rationNum;
this.selectArea = selectArea;
this.due = due;
}
public String getDue() {
return due;
}
public void setDue(String due) {
this.due = due;
}
public String getSelectArea() {
return selectArea;
}
public void setSelectArea(String selectArea) {
this.selectArea = selectArea;
}
public String getConnectionNum() {
return connectionNum;
}
public void setConnectionNum(String connectionNum) {
this.connectionNum = connectionNum;
}
public String getDoorNum() {
return doorNum;
}
public void setDoorNum(String doorNum) {
this.doorNum = doorNum;
}
public String getConName() {
return conName;
}
public void setConName(String conName) {
this.conName = conName;
}
public String getPhoneNum() {
return phoneNum;
}
public void setPhoneNum(String phoneNum) {
this.phoneNum = phoneNum;
}
public String getAadharNum() {
return aadharNum;
}
public void setAadharNum(String aadharNum) {
this.aadharNum = aadharNum;
}
public String getRationNum() {
return rationNum;
}
public void setRationNum(String rationNum) {
this.rationNum = rationNum;
}
}
将数据添加到 firebase 效果很好。这是我的数据库结构。
这是我的 showData()
方法,其中调用 .getDoorNum()
以将其显示在 ListView 上。
private void showData(DataSnapshot dataSnapshot) {
if (expandableListView.getVisibility()==View.VISIBLE) {
for (DataSnapshot ds : dataSnapshot.getChildren()) {
ConnectionInformation cInfo = new ConnectionInformation();
cInfo.setDoorNum(ds.child(userID).child("Connection Detail").child(areaName).child(key).getValue(ConnectionInformation.class).getDoorNum());
cInfo.setPhoneNum(ds.child(userID).child("Connection Detail").child(areaName).child(key).getValue(ConnectionInformation.class).getPhoneNum());
cInfo.setAadharNum(ds.child(userID).child("Connection Detail").child(areaName).child(key).getValue(ConnectionInformation.class).getAadharNum());
cInfo.setRationNum(ds.child(userID).child("Connection Detail").child(areaName).child(key).getValue(ConnectionInformation.class).getRationNum());
ArrayList<String> users = new ArrayList<>();
users.add(cInfo.getDoorNum());
users.add(cInfo.getPhoneNum());
users.add(cInfo.getAadharNum());
users.add(cInfo.getRationNum());
ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, users);
expandableListView.setAdapter(adapter);
}
}
}
我使用此代码删除 child 。
disBTN.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mdata.child(oldArea).child(key).removeValue();
connection.child(oldArea).child(key).removeValue();
toast("Connection Number " + oldNum + " Disconnected Successfully");
startActivity(new Intent(DisconnectActivity.this,AreaGridActivity.class));
}
});
代码在数据库中运行良好,但我的应用程序因此错误而崩溃...
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String trickandroid.fulllogin.ConnectionInformation.getDoorNum()' on a null object reference
at trickandroid.fulllogin.DetailsActivity.showData(DetailsActivity.java:449)
at trickandroid.fulllogin.DetailsActivity.access$100(DetailsActivity.java:33)
at trickandroid.fulllogin.DetailsActivity$3.onDataChange(DetailsActivity.java:129)
at com.google.android.gms.internal.zzbpx.zza(Unknown Source)
at com.google.android.gms.internal.zzbqx.zzZS(Unknown Source)
at com.google.android.gms.internal.zzbra$1.run(Unknown Source)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6236)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:891)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:781)
https://gist.github.com/SimonPeter1909/d70be328dd6d9b099a8a96454922432f DetailsActivity.java
我试了很多方法都无法通过错误...
最佳答案
这里的情况是您有一个 ValueEventListener
,它在添加监听器时触发一次,然后在数据更改时再次触发。监听器明确期望找到具有特定 areaName
和 key
的条目。
这在监听器第一次运行时很好,但是在单击按钮时,您会删除带有该 areaName
和 key
的条目。这再次触发监听器(您更改了数据),监听器尝试对那个 areaName
和 key
处的条目做一些事情,它不存在,你得到一个NullPointerException
。
有很多方法可以避免这种情况,但您可能需要重新考虑流程以及您想要发生的事情。
此处的快速解决方法是在尝试使用之前尝试检查该条目是否存在:
if(ds.child(userID).child("Connection Detail").child(areaName).child(key).exists()) {
ConnectionInformation cInfo = new ConnectionInformation();
cInfo.setDoorNum(ds.child(userID).child("Connection Detail").child(areaName).child(key).getValue(ConnectionInformation.class).getDoorNum());
cInfo.setPhoneNum(ds.child(userID).child("Connection Detail").child(areaName).child(key).getValue(ConnectionInformation.class).getPhoneNum());
...
...
} else {
//that entry doesn't exist, do something else
}
关于Android - 在 firebase 数据库中杀死一个 child 会杀死我的应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44288309/