2017-01-18 2 views
0

У меня есть приложение с 2 фрагментами. Нажатие на первый фрагмент приведет ко второму фрагменту, который активирует вызов БД (Async) для извлечения данных из базы данных Firebase. Второй фрагмент будет заполнен данными после завершения вызова БД. Проблема заключается в том, что я нажимаю кнопку «Назад» на втором фрагменте, когда вызов БД все еще продолжается. Нажатие кнопки «Назад» приводит к первому фрагменту, который хорош, но приложение выходит из строя, когда возвращается вызов БД (чтобы найти, что второй фрагмент больше не доступен). Я могу точно видеть (показано ниже), какая часть кода выбрасывает исключение нулевого указателя, но мне нужна помощь в понимании того, каким будет лучший способ справиться с этой проблемой.Фрагмент Android недоступен (приводящий к сбою), когда результаты DB возвращаются

Фрагмент кода, который делает DB позвонить

mDatabase = FirebaseDatabase.getInstance().getReference(DBReference); 
Query myQuery = mDatabase.orderByChild("title"); 

    myQuery.addListenerForSingleValueEvent(new ValueEventListener() { 
     @Override 
     public void onDataChange(DataSnapshot snapshot) { 

      for (DataSnapshot postSnapshot : snapshot.getChildren()) { 
       ContactItem post = postSnapshot.getValue(ContactItem.class); 

       ContactItem item = new ContactItem(); 
       item.status = post.getStatus(); 
       item.title = post.getTitle(); 
       itemList.add(item); 
      } 
      // Transaction complete, sending to listener 
      dataListener.newDataReceived(itemList); 
     } 

Фрагмент кода во втором фрагменте, где обратный вызов принимается после того, как операция БД завершена.

public void newDataReceived(ArrayList<ContactItem> itemList) { 
    progressCircle.setVisibility(View.GONE); 
    adapter = new ContactItemAdapter(this.getActivity(), itemList, contactType); 

код адаптера, где Null Pointer исключение брошено

public ContactItemAdapter(Context context, ArrayList<ContactItem> items, String contactType) { 
    mContext = context; 
    mDataSource = items; 
    mDataSourceCopy = new ArrayList<ContactItem>(mDataSource); 
    //Null pointer exception is thrown at below line 
    mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    mType = contactType; 
    } 
+0

Ваше решение находится в вашей проблеме. Ваша асинхронная задача выполняется, и вы нажимаете кнопку «Назад», вам нужно сначала остановить асинхронную задачу на обратной кнопке, если она все еще выполняется. Поскольку вы выполняете некоторые задачи пользовательского интерфейса после завершения асинхронной задачи. –

+0

AsyncTask.cancel(), вы можете отменить свою асинхронную. –

+0

Возможно, я ошибся, заявив, что это вызов Async. По Async я подразумевал, что приложение позволяет пользователю нажимать кнопку, даже когда выполняется вызов БД. – dacscan3669

ответ

1

Убедитесь, что ваш фрагмент добавляется к активности в методе newDataReceived. Вы можете сделать это, используя isAdded, isDetached или isRemoving в обратном вызове из фрагмента.

public void newDataReceived(ArrayList<ContactItem> itemList) { 
    if(isAdded()){ 
    progressCircle.setVisibility(View.GONE); 
    adapter = new ContactItemAdapter(this.getActivity(), itemList, contactType); 
    } 
} 
+0

Можете ли вы подробнее остановиться на этом. Как проверить, добавлен ли фрагмент? isDetached и isRemoving - стандартные методы? – dacscan3669

+0

Они встроены в класс Fragment, поэтому вы можете использовать их в своем обратном вызове из запроса БД. https://developer.android.com/reference/android/app/Fragment.html#isAdded() –

+0

Спасибо. Я пробовал печатать состояния, и он правильно фиксирует состояние фрагмента. Я буду строить вокруг него логику. Еще раз спасибо! – dacscan3669

Смежные вопросы