2015-11-15 4 views
4

Мне нужно сохранить результат метода getBalue FireBase, который является асинхронным по своему усмотрению. Я не могу использовать что-то вроде «onPostExecute()», и для моей цели я не могу выполнить всю свою операцию «в onDataChange()», потому что мне нужны ссылки в будущем в других действиях.Wait Firebase async извлекает данные в android

Вот мой сниппет для извлечения данных:

List<Village> villages = new LinkedList<>(); 
    Firebase ref = new Firebase("MYFIREBASEURL").child("village"); 
    ref.addValueEventListener(new ValueEventListener() { 
     @Override 
     public void onDataChange(DataSnapshot snapshot) { 
      spinnerArray.clear(); 
      for (DataSnapshot postSnapshot : snapshot.getChildren()) { 
       Village v = postSnapshot.getValue(Village.class); 
       villages.add(v); 
      } 
     } 

     @Override 
     public void onCancelled(FirebaseError firebaseError) { 
      System.out.println("The read failed: " + firebaseError.getMessage()); 
     } 
    }); 

Если я пытаюсь читать деревни из «OnDataChange» Я, естественно для его асинхронным жизни, нулевое значение. Есть способ гарантировать, что onDataChange был вызван ?.

Заранее спасибо.

+2

Вы, вам нужно перефразировать ваши потребности в «всякий раз, когда данные меняются, я хочу делать ABC». Или вы можете дождаться данных, это возможно, как правило, не рекомендуется. См. Этот вопрос и ответы для деталей/образцов: http://stackoverflow.com/questions/33203379/setting-singleton-property-value-in-firebase-listener –

ответ

12

Извините, если это не то, что вы хотите, потому что мой английский слишком плохой. Вы можете определить интерфейс прослушивателя для его обработки. Пример:

public interface OnGetDataListener { 
    public void onStart(); 
    public void onSuccess(DataSnapshot data); 
    public void onFailed(DatabaseError databaseError); 
} 

И создать пользовательскую функцию, чтобы получить данные в Database.class:

public void mReadDataOnce(String child, final OnGetDataListener listener) { 
    listener.onStart(); 
    FirebaseDatabase.getInstance().getReference().child(child).addListenerForSingleValueEvent(new ValueEventListener() { 
     @Override 
     public void onDataChange(DataSnapshot dataSnapshot) { 
      listener.onSuccess(dataSnapshot); 
     } 

     @Override 
     public void onCancelled(DatabaseError databaseError) { 
      listener.onFailed(databaseError); 
     } 
    }); 
} 

Когда я хочу, чтобы получить данные из Main.class, я:

private void mCheckInforInServer(String child) { 
    new Database().mReadDataOnce(child, new OnGetDataListener() { 
     @Override 
     public void onStart() { 
      //DO SOME THING WHEN START GET DATA HERE 
     } 

     @Override 
     public void onSuccess(DataSnapshot data) { 
      //DO SOME THING WHEN GET DATA SUCCESS HERE 
     } 

     @Override 
     public void onFailed(DatabaseError databaseError) { 
      //DO SOME THING WHEN GET DATA FAILED HERE 
     } 
    }); 

} 

Таким образом, вы можете повторно использовать свой метод и обрабатывать данные.

+0

Это не устраняет проблему. Асинхронный вызов проходит, как обычно, только для получения данных после его необходимости. – Flaom

0

Просто, чтобы добавить к ответу Мань, в один бы назвать onStart() как раз перед

FirebaseDatabase.getInstance().getReference().child(child).addListenerForSingleValueEvent(new ValueEventListener() { 

И в onStart(), как правило, вы бы показать progressDialog:

if (mProgressDialog == null) { 
     mProgressDialog = new ProgressDialog(getContext()); 
     mProgressDialog.setMessage(getString(R.string.loading)); 
     mProgressDialog.setIndeterminate(true); 
    } 

    mProgressDialog.show(); 

И в onSuccess() закрыть диалоговое окно и нагрузки данные в GUI (или что вы хотите сделать)

if (mProgressDialog != null && mProgressDialog.isShowing()) { 
     mProgressDialog.dismiss(); 
    } 
Смежные вопросы