Как выполнить метод успеха в 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