2016-01-10 4 views
1

Я пытаюсь установить ListView внутри моего Fragment. Я получаю данные от Firebase, которые я установил для своего ListView. В моей базе данных Firebase у меня есть родительский узел patients, у которого есть дочерние узлы, такие как patient1, patient2 и т. Д., И каждый элемент в моем ListView представляет одного пациента. Мой ListView всегда будет иметь максимум 2 элемента, поскольку я устанавливаю свой список с двумя лучшими пациентами из базы данных Firebase. Всякий раз, когда новый пациент добавляется или удаляется, я хочу, чтобы мой listView обновился с новыми данными пациента. Но когда новый пациент добавлен, мое приложение разбивается.notifyDataSetChanged() вызывает NullPointerException при изменении данных списка, которые извлекаются из firebase

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

Отладка вашего кода и проверка вашего пациентаЛист возвращается как null. \ –

+0

patientList не становится нигде, хотя patientList иногда может быть пустым, в этом случае в списке ничего не будет. –

+0

java.lang.NullPointerException: попытка вызвать виртуальный метод 'java.lang.String java.lang.Object.toString() 'на ссылке нулевого объекта вы возвращаетесь к объекту, который является нулевым, проверьте ваш объект 1-й, если его значение не равно null, тогда реализуйте свою логику в нем, например: if (object! = null) { что-то здесь делать}' –

ответ

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 в Integer.

Пример:

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

Этот код также будет установлен на нуль tempId если appointment-id содержит не целочисленное значение, такое как xyz или 234.0.

+0

Я получил решение. Проблема действительно была вызвана тем, что одно из вышеупомянутых значений было аннулировано. Причина заключалась в том, как я сохранял данные в firebase. Я использовал 'setValue()' вместо 'updateChildren()', из-за чего мой узел 'пациентов' удалялся за долю секунды, поскольку метод' setValue() 'удаляет весь путь и снова переписывает путь с обновленными данными. И поскольку узел «пациентов» отсутствовал для этой части секунды, он выдавал мне «NullPointerException». В любом случае, спасибо. –