android - notifyDataSetChanged() 在更改从 firebase 检索的 ListView 数据时导致 NullPointerException

标签 android android-listview firebase

我正在尝试在我的 Fragment 中设置一个 ListView。我正在从 Firebase 获取数据,并将其设置为我的 ListView。在我的 Firebase 数据库中,我有一个父节点 patients,它有 patient1patient2 等子节点以及我的 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) {}
        });

    }

我不知道我在这里错过了什么。这可能是一个非常基本的事情,我错了,希望有人纠正我。

最佳答案

错误消息说:“java.lang.NullPointerException:尝试在空对象引用上调用虚方法‘java.lang.String java.lang.Object.toString()’”

您在从 Firebase 提取数据的代码中调用了 toString():

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。然后您可以在这些字段中存储空值,但您必须处理它们在程序的其余部分中为空值的可能性。

另一种可能性是,如果传入值为空,则使用一些默认值。

此外,如 Firebase documentation 中所述, getValue() 返回一个已解析的对象,例如Long 如果数据是整数,那么我们可以使用它来避免解析速度有点慢,只需将 Long 转换为 Integer。

例子:

Object tempIdObj = tempSnapshot.child("appointment-id").getValue();
Integer tempId = tempIdObj instanceof Long ? ((Long) tempIdObj).intValue() : null;

如果 appointment-id 包含非整数值,例如 xyz234.0,此代码还将设置 tempId 为 null。

关于android - notifyDataSetChanged() 在更改从 firebase 检索的 ListView 数据时导致 NullPointerException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34703775/

相关文章:

android - 添加聊天和 VOIP 通话功能?

firebase - DNS - Firebase 连接到 Namecheap 仍然显示需要设置?

android - 恢复 UploadTask 导致 E/StorageException : BufferedInputStream is closed

android - 如何在 Android 中使用内容解析器插入文件?

android - Android录音无法在按钮上单击

android - 如何捕获java.lang.RuntimeException : Could not deserialize object from Firebase ClassMapper and add default Values

android - 如何查看特定 ListView 项的详细数据

android - 将 ListView 项目放在可见区域的中心

android - 如何下载图像(数千张图像)并在 Android 的 ListAdapter 中渲染它们?

python - Firebase(客户端与服务器端)