Как выполнить метод успеха в Firebase?

Я занимаюсь разработкой приложения для Android+Firebase, но, поскольку я новичок в обеих технологиях, у меня возникла проблема с асинхронными вызовами, и я пока не нашел решения, поэтому надеюсь, что вы мне поможете.

У меня есть следующий фрагмент в моей деятельности onCreate метод:

final ArrayList<AssetLocation> assetsLocations = new ArrayList<>();
        DatabaseReference assetsLocationReference = database.getReference(FirebaseReferences.ASSETSLOCATION_REFERENCE);
        assetsLocationReference.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot snapshot) {
                ArrayList<String> assetsLocationSpinner = new ArrayList<String>();
                // Create an ArrayAdapter using the string array and a default spinner layout
                for (DataSnapshot postSnapshot : snapshot.getChildren()) {
                    //Getting the data from snapshot
                    AssetLocation assetsLocation = postSnapshot.getValue(AssetLocation.class);
                    assetsLocations.add(AssetLocation);
                }
            }

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

У меня также есть довольно похожий вызов, но вместо того, чтобы получать Locations, я получаю Types.

После этого кода (также внутри метода onCreate) я вызываю setScreenInfo Это функция, которая заполняет оба счетчика (и делает больше вещей) указанными данными, но, поскольку это асинхронный вызов, счетчики остаются пустыми, когда я их выполняю.

Как я могу выполнить setScreenInfo как только звонки сделаны? Я пробовал с .once()/.on() но это не распознается Android Studio как функция.

Спасибо за вашу помощь!

3 ответа

Решение

Из-за асинхронного поведения вам нужно переместить объявление assetsLocations ArrayList:

final ArrayList<AssetLocation> assetsLocations = new ArrayList<>();

внутри onDataChange() метод, как assetsLocationSpinner ArrayList есть. Так что помни, onDataChange всегда называется asynchronously, Это означает, что оператор, который добавляет объекты AssetLocation класс в списке выполняется раньше onDataChange был вызван. Вот почему ваш список пуст за пределами этого метода.

Для другого подхода, пожалуйста, посетите этот пост и этот пост.

Надеюсь не поможет.

После этого кода (также внутри метода onCreate) я вызываю функцию setScreenInfo, которая является функцией для заполнения обоих счетчиков (и выполнения дополнительных действий) указанными данными, но, поскольку это асинхронный вызов, счетчики остаются пустыми, когда я выполняю их,

Вам не разрешено изменять пользовательский интерфейс из фонового потока. Обычно я звоню runOnUIThread, передавая новый Runnable() и final копия данных, которые я хочу передать.

        final String myData = "updateData";

        ActivityName.this.runOnUiThread(new Runnable() {

            public void run() {
                // use myData to update UI
            }
        });

Тем не менее, похоже, что есть миграция в AsyncTask: Преобразование runOnUiThread в AsyncTask

Лично я до сих пор пользуюсь runOnUIThread, Это более явно.

Вы можете использовать поток:

thread = new Thread() {

    @Override
    public void run() {

        try {
            //background tasks

            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    //UI tasks
                }
            });
        }
        catch (JSONException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
};
    thread.start();`

Или вы можете использовать метод Firebase Multi Query. ссылка: загружать макет только после завершения вызовов firebase

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