Как заполнить Android ListView информацией из запроса Firebase

Это мой первый пост, поэтому, если я не выполнил какой-то протокол, я должен был извиниться.

Я пытаюсь заполнить ListView некоторой информацией из моей базы данных Firebase. Я думаю, что проблема, с которой я сталкиваюсь, заключается в том, что запрос к базе данных слишком медленный (поток, вероятно, загружает изображения), и моя активность загружает макет активности, не дожидаясь завершения выполнения потока. (Если я пройду через отладчик и немного подожду, я в конечном итоге увижу информацию, которую я разбору: имена пользователей, номера пользователей и изображения пользователей). Все, что я запросил, предполагает, что я должен использовать AsyncTask для этого. В отличие от использования блокировки потоков или семафора b / c AsyncTask является потокобезопасным.

Насколько я понимаю, запросы Firebase уже выполняются асинхронно; Поэтому метод doInBackground для AsyncTask, который я «пытался» реализовать, кажется излишним. Кроме того, я немного смущен перегруженной сигнатурой AsyncTask и вызовом: new someTask.execute («некоторые вещи в строке»).

Любые предложения о том, как я могу это сделать? Любая обратная связь очень ценится!

// Пожалуйста, игнорируйте второстепенный отступ от вставки моего кода в

protected void onCreate(Bundle savedInstanceState) { ... new getFirebaseInfoTask(); } private class getFirebaseInfoTask extends AsyncTask { @Override protected Object doInBackground(Object... args) { // Do stuff userInfoList = GetUserInfoFromFirebase.getUserInfo(); // Unsure if I need to return here. return userInfoList; } @Override protected void onProgressUpdate(Object... args) { // Update your UI here populateUserInfoList(); } } private void populateUserInfoList() { // Create list of items Collections.addAll(userInfoList); populateFriendsListView(); } private void populateFriendsListView() { // Build the adapter ArrayAdapter<UserInfo> adapter = new MyListAdapter(); // Configure the list view ListView listView = (ListView) findViewById(R.id.friends_listview); listView.setAdapter(adapter); registerClickCallBack(); } ... // More code public class GetUserInfoFromFirebase { public static ArrayList getUserInfo() { final ArrayList<UserInfo> list = new ArrayList<UserInfo>(); Firebase firebase = new Firebase("https:......firebaseio.com"); firebase.child("users").addValueEventListener(new ValueEventListener() { @Override public void onDataChange(DataSnapshot snapshot) { HashMap<String, Object> users = (HashMap<String, Object>) snapshot.getValue(); for(Object user : users.values()) { HashMap<String, Object> userMap = (HashMap<String, Object>) user; String userNumber = (String) userMap.remove("number"); if(!list.contains(userNumber)) { String name = (String) userMap.remove("username"); String pic = (String) userMap.remove("profile_picture"); UserInfo info = new UserInfo(userNumber, name, pic); list.add(info); } } } @Override public void onCancelled(FirebaseError firebaseError) {} }); return list; } 

Поэтому я понял это. Я избавился от AsyncTask и переместил вызов метода, который я хотел выполнить в onProgressUpdate, за пределами цикла for моего onDataChange, так что поток, который фактически получает доступ к методу onDataChange, вызывает мой метод populateFriendsView.

 private void populateUserInfoList() { userInfoList = new ArrayList<UserInfo>(); firebase = new Firebase("https://....firebaseio.com"); firebase.child("users").addValueEventListener(new ValueEventListener() { @Override public void onDataChange(DataSnapshot snapshot) { HashMap<String, Object> users = (HashMap<String, Object>) snapshot.getValue(); for (Object user : users.values()) { HashMap<String, Object> userMap = (HashMap<String, Object>) user; String userNumber = (String) userMap.remove("number"); if (!userInfoList.contains(userNumber)) { String name = (String) userMap.remove("username"); String pic = (String) userMap.remove("profile_picture"); UserInfo info = new UserInfo(userNumber, name, pic); userInfoList.add(info); } } // thread executing here can get info from database and make subsequent call Collections.addAll(userInfoList); populateFriendsListView(); } @Override public void onCancelled(FirebaseError firebaseError) { String message = "Server error. Refresh page"; Toast.makeText(context, message, Toast.LENGTH_SHORT).show(); } }); } 

Firebase сама предоставляет асинхронные методы для запроса данных. Они создали пример приложения, чтобы показать, как создать резервную копию Listview с информацией о firebase через Android Chat

Проверь это

В этом примере основная функциональность размещена в базовом адаптере под названием FirebaseListAdapter …

Фрагмент из моей рабочей базы кода

  Firebase firebase = new Firebase(Constants.FREEBASE_DB_URL); Firebase childRef = firebase.child("sessions"); childRef.addValueEventListener(new ValueEventListener() { @Override public void onDataChange(DataSnapshot snapshot) { System.out.println(snapshot.getValue()); Map<String, Session> td = (HashMap<String, Session>) snapshot.getValue(); List<Session> valuesToMatch = new ArrayList<Session>(td.values()); apiClientCallback.onSuccess(valuesToMatch); } @Override public void onCancelled(FirebaseError error) { Toast.makeText(context, "onCancelled" + error.getMessage(), Toast.LENGTH_SHORT).show(); } });