2014-12-11 89 views
4

这是我的第一篇文章,所以如果我没有遵循某些协议,我应该表示歉意。如何使用来自Firebase查询的信息填充Android ListView

我想从我的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; 
} 
+1

所以我想通了。我摆脱了AsyncTask,并将我想在onProgressUpdate中执行的方法调用移动到我的onDataChange的for循环之外,以便实际访问onDataChange方法的线程调用我的populateFriendsView方法。 – cshort12 2014-12-11 07:26:52

+0

很高兴听到您找到答案,并感谢您回报。你能否提供这些信息作为答案(你可能必须等待一段时间才允许这样做)?然后你也可以接受你自己的答案,这有助于建立你的声望得分。 – 2014-12-11 16:55:41

+0

感谢您的反馈@FrankvanPuffelen。 – cshort12 2014-12-14 00:00:46

回答

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

火力地堡本身提供异步方法来查询数据,他们已经创建了一个示例应用程序来说明如何通过Android的聊天

check this

备份与火力信息的列表视图在该示例中的核心功能放置在名为FirebaseListAdapter的通用基本适配器中...

+0

但是,我没有机会深入研究这个问题,但是,谢谢!毫无疑问,我很快就会看到这一点。 另外,就我以前的解决方案而言,我了解到最好在条件变量上使用侦听器,以便准确指示何时完成对Firebase的异步调用。这显然是比嵌套我的方法调用更好的解决方案。 – cshort12 2015-04-24 15:13:05

0

从我的工作代码库中摘录代码

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

我得到这个错误:'java.lang.ClassCastException:java.util.ArrayList不能转换为java.util.HashMap' – Hesam 2016-06-12 04:28:36

+0

@Hesam你做到了。你能帮我解决这个错误吗? – 2017-10-06 22:50:36

相关问题