如何使用Firebase查询中的信息填充Android ListView

cor*_*ort 5 java android android-asynctask firebase firebase-realtime-database

这是我的第一篇文章,所以如果我没有按照我应该遵循的协议,道歉.

我正在尝试使用Firebase数据库中的一些信息填充ListView.我认为我遇到的问题是对数据库的查询太慢(线程可能正在下载图片)并且我的活动加载其活动布局而不等待线程完成执行.(如果我单步执行调试器并稍等一下,我将最终看到我正在解析的信息:用户名,用户号和用户图片)我查询的所有内容都表明我应该使用AsyncTask来完成此任务.与使用线程阻塞或信号量b/c相反,AsyncTask是线程安全的.

据我了解,Firebase查询已经异步执行; 因此,我已经"尝试"实现的AsyncTask的doInBackground方法似乎是多余的.另外,我对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;
}
Run Code Online (Sandbox Code Playgroud)

cor*_*ort 2

所以我想通了。我摆脱了 AsyncTask 并将我想要在 onProgressUpdate 中执行的方法调用移动到 onDataChange 的 for 循环之外,以便实际访问 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();
        }
    });
}
Run Code Online (Sandbox Code Playgroud)