【问题标题】:How to populate Android ListView with information from Firebase query如何使用来自 Firebase 查询的信息填充 Android ListView
【发布时间】:2014-12-11 02:23:50
【问题描述】:

这是我的第一篇文章,所以如果我没有遵守我应该遵守的一些协议,请道歉。

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

据我了解,Firebase 查询已经在异步执行;因此,我“尝试”实现的 AsyncTask 的 doInBackground 方法似乎是多余的。另外,我对 AsyncTask 的重载签名和对以下内容的调用有点困惑:new someTask.execute("some stuff in a string")。

关于如何完成此任务的任何建议?非常感谢任何反馈!

//粘贴我的代码时请忽略小缩进

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 中执行的方法调用移到我的 onDataChange 的 for 循环之外,以便实际访问 onDataChange 方法的线程调用我的 populateFriendsView 方法。
  • 很高兴听到您发现并感谢您的反馈。您能否提供该信息作为答案(您可能需要稍等片刻才能被允许这样做)?然后,您也可以接受自己的答案,这有助于建立您的声誉得分。
  • 感谢@FrankvanPuffelen 的反馈。
  • Firebase 还有一个操作系统库,可以自动填充 ListView:github.com/firebase/firebaseui-android

标签: java android android-asynctask firebase firebase-realtime-database


【解决方案1】:

所以我想通了。我摆脱了 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();
        }
    });
}

【讨论】:

    【解决方案2】:

    Firebase 本身提供了异步方法来查询数据,他们创建了一个示例应用程序来展示如何通过 Android Chat 使用 Firebase 信息备份 Listview

    check this

    在该示例中,核心功能放置在名为 FirebaseListAdapter 的通用基础适配器中...

    【讨论】:

    • 我没有机会对此进行深入了解,但是,谢谢!毫无疑问,我很快就会对此一目了然。此外,关于我之前的解决方案,我了解到最好在条件变量上使用监听器,以便准确地发出对 Firebase 的异步调用何时完成的信号。这显然是比嵌套我的方法调用更好的解决方案。
    【解决方案3】:

    我的工作代码库中的片段

      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();
                    }
                });
    

    【讨论】:

    • 我收到这个错误:`java.lang.ClassCastException: java.util.ArrayList cannot be cast to java.util.HashMap`
    • @Hesam 你做到了吗。你能帮我解决这个错误吗
    猜你喜欢
    • 1970-01-01
    • 2015-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-06
    • 1970-01-01
    • 2023-03-15
    • 1970-01-01
    相关资源
    最近更新 更多