Ожидание 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 Функция для вашей пользовательской функции снаружи и сохранить данные снимка в глобальной переменной. Затем вы можете использовать переменную, как вы хотите.

Другие вопросы по тегам