如何填充的Andr​​oid的ListView从火力地堡的查询信息 [英] How to populate Android ListView with information from Firebase query

查看:221
本文介绍了如何填充的Andr​​oid的ListView从火力地堡的查询信息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的第一篇,所以如果我没有按照某种协议,我应该,道歉。

我试图来用我的火力地堡数据库中的一些信息,一个ListView。我想,我遇到的问题是,数据库查询速度太慢(线程可能是下载图片)和我的活动加载其活性的布局,而无需等待线程执行完毕。 (如果我步调试器和稍等一下,我最终会看到我解析的信息:用户名,用户数量和用户的图片)我质疑一切都表明我应该使用的AsyncTask做到这一点。相对于使用线程阻塞或信号B / C AsyncTask的是线程安全的。

据我了解,火力地堡查询已经异步执行;因此,对于的AsyncTask doInBackground方法我都尝试的实施似乎是多余的。此外,我有点糊涂的AsyncTask的重载签名和调用:新someTask.execute(一些东西在一个字符串)

我如何能做到这一点有什么建议?任何反馈是非常AP preciated!

//请从我的贴code在

忽略轻微压痕

 保护无效的onCreate(捆绑savedInstanceState){
    ...
    新getFirebaseInfoTask();
}私有类getFirebaseInfoTask扩展的AsyncTask {    @覆盖
    保护对象doInBackground(对象参数... args){
        //做的东西
        userInfoList = GetUserInfoFromFire​​base.getUserInfo();
        //不能确定,如果我需要回到这里。
        返回userInfoList;
    }    @覆盖
    保护无效onProgressUpdate(对象参数... args){
        //此处更新你的UI
        populateUserInfoList();
    }
}
私人无效populateUserInfoList(){
    //创建项目列表
    Collections.addAll(userInfoList);
    populateFriendsListView();}
私人无效populateFriendsListView(){
    //构建适配器
    ArrayAdapter<&的UserInfo GT;适配器=新MyListAdapter();    //配置列表视图
    ListView控件的ListView =(ListView控件)findViewById(R.id.friends_listview);
    listView.setAdapter(适配器);    registerClickCallBack();
}... //更多code
公共类GetUserInfoFromFire​​base {公共静态的ArrayList getUserInfo(){
    最终的ArrayList<&的UserInfo GT;名单=新的ArrayList<&的UserInfo GT;();
    火力地堡火力点=新的火力点(HTTPS:...... firebaseio.com);
    firebase.child(用户)。addValueEventListener(新ValueEventListener(){
        @覆盖
        公共无效onDataChange(DataSnapshot快照){
            HashMap的<弦乐,对象>用户=(HashMap的<弦乐,对象>)snapshot.getValue();
            为(对象用户:users.values​​()){
                HashMap的<弦乐,对象>中userMap =(HashMap的<弦乐,对象>)的用户;
                字符串userNumber =(字符串)userMap.remove(数字);
                如果(!list.contains(userNumber)){
                    字符串名称=(字符串)userMap.remove(用户名);
                    字符串PIC =(字符串)userMap.remove(profile_picture);
                    的UserInfo信息=新的UserInfo(userNumber,姓名,PIC);
                    list.add(信息);
                }
            }
        }
        @覆盖
        公共无效onCancelled(FirebaseError firebaseError){}
    });
    返回列表;
}


解决方案

所以我想通了。我摆脱了AsyncTask的和移动的方法调用我想在onProgressUpdate执行到外面为我onDataChange的循环,使得实际获取的onDataChange方法访问线程调用我的populateFriendsView方法。

 私人无效populateUserInfoList(){
    userInfoList =新的ArrayList<&的UserInfo GT;();
    火力点=新的火力地堡(HTTPS://....firebaseio.com);
    firebase.child(用户)。addValueEventListener(新ValueEventListener(){
        @覆盖
        公共无效onDataChange(DataSnapshot快照){
            HashMap的<弦乐,对象>用户=(HashMap的<弦乐,对象>)snapshot.getValue();
            为(对象用户:users.values​​()){
                HashMap的<弦乐,对象>中userMap =(HashMap的<弦乐,对象>)的用户;
                字符串userNumber =(字符串)userMap.remove(数字);
                如果(!userInfoList.contains(userNumber)){
                    字符串名称=(字符串)userMap.remove(用户名);
                    字符串PIC =(字符串)userMap.remove(profile_picture);
                    的UserInfo信息=新的UserInfo(userNumber,姓名,PIC);
                    userInfoList.add(信息);
                }
            }
            //线程执行在这里可以从数据库中获取信息并进行后续调用
            Collections.addAll(userInfoList);
            populateFriendsListView();
        }
        @覆盖
        公共无效onCancelled(FirebaseError firebaseError){
            字符串消息=服务器错误刷新页面。
            Toast.makeText(背景下,消息,Toast.LENGTH_SHORT).show();
        }
    });
}

This is my first post so if I didn't follow some protocol I was supposed to, apologies.

I am trying to populate a ListView with some information from my Firebase database. I think the problem I am having is that the query to the database is too slow (the thread is probably downloading pictures) and my activity loads its activity layout without waiting for the thread to finish executing. (If I step through the debugger and wait a bit, I will eventually see the information I am parsing: user names, user numbers, and user pictures) Everything I have queried suggests I should use AsyncTask to accomplish this. As opposed to using thread blocking or a semaphore b/c AsyncTask is thread safe.

To my understanding, Firebase queries are already executing asynchronously; therefore, the doInBackground method for AsyncTask I have "tried" to implement seems redundant. Also, I am a bit confused of AsyncTask's overloaded signature and the call to: new someTask.execute("some stuff in a string").

Any suggestions on how I can accomplish this? Any feedback is very much appreciated!

// Please ignore the minor indentation from pasting my code in

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

解决方案

So I figured it out. I got rid of the AsyncTask and moved the method call I wanted to execute in onProgressUpdate to outside of the for loop of my onDataChange such that the thread that actually gets access to the onDataChange method calls my populateFriendsView method.

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

这篇关于如何填充的Andr​​oid的ListView从火力地堡的查询信息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆