我正在尝试在ListView
内设置Fragment
。我从Firebase获取数据,我将其设置为ListView
。在我的Firebase数据库中,我有一个父节点patients
,其中包含patient1
,patient2
等子节点,我ListView
中的每个项目代表一个患者。我的ListView
总是最多有2个项目,因为我正在使用Firebase数据库中的前两名患者设置我的列表。每当添加或删除新患者时,我希望我的listView
更新新的患者数据。但是当添加新患者时,我的应用程序会崩溃。
Logcat例外: -
01-10 14:20:20.966 17863-17863/com.abc.tempapp/AndroidRuntime: FATAL EXCEPTION: main
01-10 14:20:20.966 17863-17863/com.abc.tempapp E/AndroidRuntime: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.Object.toString()' on a null object reference
代码: -
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState)
{
...
setListView();
...
}
public void setListView()
{
Firebase.setAndroidContext(context);
firebaseData = new Firebase("https://xyz.firebaseio.com");
firebaseData.child("patients").orderByChild("appointment-id").limitToFirst(2).addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
patientList.clear();
for (DataSnapshot tempSnapshot : dataSnapshot.getChildren()) {
int tempId = Integer.parseInt(tempSnapshot.child("appointment-id").getValue().toString());
String tempContact = tempSnapshot.child("number").getValue().toString();
String tempName = tempSnapshot.child("name").getValue().toString();
long tempTime = Long.parseLong(tempSnapshot.child("arrival-time").getValue().toString());
Patient patient = new Patient(tempId, tempContact, tempName, epochToDate(tempTime));
patientList.add(patient);
}
if (myAdapter == null) {
myAdapter = new MyAdapter(context, patientList);
listView.setAdapter(myAdapter);
firebaseData.child("patients").addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
dataChanged();
}
@Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
dataChanged();
}
@Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {}
@Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {}
@Override
public void onCancelled(FirebaseError firebaseError) {}
});
}
}
@Override
public void onCancelled(FirebaseError firebaseError) {}
});
}
synchronized public void dataChanged()
{
Firebase.setAndroidContext(context);
firebaseData = new Firebase("https://xyz.firebaseio.com");
firebaseData.child("patients").orderByChild("appointment-id").limitToFirst(2).addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
patientList.clear();
for (DataSnapshot tempSnapshot : dataSnapshot.getChildren()) {
int tempId = Integer.parseInt(tempSnapshot.child("appointment-id").getValue().toString());
String tempContact = tempSnapshot.child("number").getValue().toString();
String tempName = tempSnapshot.child("name").getValue().toString();
long tempTime = Long.parseLong(tempSnapshot.child("arrival-time").getValue().toString());
Patient patient = new Patient(tempId, tempContact, tempName, epochToDate(tempTime));
patientList.add(patient);
}
myAdapter.notifyDataSetChanged();
}
@Override
public void onCancelled(FirebaseError firebaseError) {}
});
}
我不知道我在这里缺少什么。我错了可能是一件非常基本的事情,希望有人纠正我。
答案 0 :(得分:2)
错误消息说:“java.lang.NullPointerException:尝试在空对象引用上调用虚方法'java.lang.String java.lang.Object.toString()'”
您的代码中有toString()
次调用,您从Firebase中提取数据:
int tempId = Integer.parseInt(tempSnapshot.child("appointment-id").getValue().toString());
String tempContact = tempSnapshot.child("number").getValue().toString();
String tempName = tempSnapshot.child("name").getValue().toString();
long tempTime = Long.parseLong(tempSnapshot.child("arrival-time").getValue().toString());
您收到的其中一个值显然是null
,因此toString()
失败。这可能是由于缺少值或者您对结果形状的错误假设造成的 - 尝试记录tempSnapshot
的内容或在那里设置断点并从调试器中查看对象。
如果空值是由通常存在但有时会丢失的数据引起的,则可以从基本类型切换到引用类型,即使用Integer而不是int和Long而不是long。然后你可以在这些字段中存储空值,但你必须处理它们在程序的其余部分中为空的可能性。
如果传入的值为null,则另一种可能性是使用一些默认值。
此外,如Firebase documentation中所述,getValue()
会返回已解析的对象,例如如果数据是整数,那么我们可以使用它来避免解析有点慢,只需将Long转换为整数。
示例:
Object tempIdObj = tempSnapshot.child("appointment-id").getValue();
Integer tempId = tempIdObj instanceof Long ? ((Long) tempIdObj).intValue() : null;
如果appointment-id
包含非整数值,例如xyz
或234.0
,此代码也会将tempId设置为null。