Ожидание Firebase асинхронного извлечения данных в Android
Мне нужно сохранить результат метода getBalue FireBase, который сам по себе является асинхронным. Я не могу использовать что-то вроде "onPostExecute()" и, для своих целей, я не могу выполнить все свои операции с "onDataChange()", потому что в будущем мне понадобятся ссылки в других действиях.
Вот мой фрагмент для извлечения данных:
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 был вызван?
3 ответа
Извините, если это не то, что вы хотите, потому что мой английский слишком плохо. Вы можете определить интерфейс слушателя, чтобы справиться с этим. Пример:
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
}
});
}
Таким образом, вы можете повторно использовать ваш метод и обрабатывать данные.
Просто чтобы добавить ответ Мана, можно было бы позвонить 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()
закрыть диалоговое окно и загрузить данные в графический интерфейс (или все, что вы хотите сделать)
if (mProgressDialog != null && mProgressDialog.isShowing()) {
mProgressDialog.dismiss();
}
Я понял, что вы пытаетесь сохранить данные снимка в переменную, но из-за асинхронной задачи переменная оказывается пустой, это из-за характера асинхронной задачи, что вы можете сделать, это передать данные снимка из слушателя firebase Функция для вашей пользовательской функции снаружи и сохранить данные снимка в глобальной переменной. Затем вы можете использовать переменную, как вы хотите.