【问题标题】:return an object Android返回一个对象 Android
【发布时间】:2015-06-03 10:26:02
【问题描述】:

我想返回一个包含一些东西的对象。

这是声明;

Object user_det = get_user_det();

功能代码如下:

        private Object get_user_det() {
        Firebase f_user = new Firebase("https://myapp.firebaseio.com/User/");
        f_user.addListenerForSingleValueEvent(new ValueEventListener(){
            @Override
            public void onDataChange(DataSnapshot snap_user) {
                // TODO Auto-generated method stub
                Iterable<DataSnapshot> rs = snap_user.getChildren();
                Iterator<DataSnapshot> irs = rs.iterator();
                long allNum2 = snap_user.getChildrenCount();
                int maxNum2 = (int)allNum2;
                int count_user = 1;
                while(irs.hasNext())
                {
                    if(count_user <= maxNum2)
                    {
                        Firebase user_data = new Firebase("https://myapp.firebaseio.com/"); 
                        AuthData authData = user_data.getAuth();
                        Map<String, Object> nPost = (Map<String, Object>) irs.next().getValue();

                        String db_email = nPost.get("email_addr").toString();

                        if (authData != null) {
                            String usr_email = authData.getProviderData().get("email").toString();
                            if(usr_email.equals(db_email))
                            {
                      //NB: I WANT TO ADD THE FOLLOWING INTO THE OBJECT
                                String disp_name = nPost.get("disp_name").toString();
                                String real_name = nPost.get("real_name").toString();
                            }

                        } else {
                            System.out.println("Failed");
                        }
                    }
                    count_user++;
                }                       
            }
            @Override
            public void onCancelled(FirebaseError arg0) {
                // TODO Auto-generated method stub

            }
    }); 
    return null; //NB: I NEED TO RETURN THE OBJECT HERE.
}

我想返回字符串 disp_name 和 real_name 但它们在 addListenerForSingleValueEvent 中,那么如何将它们取出并返回给函数。

我在需要帮助的代码中写了“NB”。

感谢您的宝贵时间。

【问题讨论】:

  • 您可以将它们添加到 ArrayList 中并返回它们.. 是吗?如果我是正确的,请告诉我。
  • @mubeen,不需要ArrayList,一个简单的String数组就可以了。

标签: android object return firebase


【解决方案1】:

如果你想从你的 java 方法中返回一个对象,这样做:


对象类: 这包含您的对象的结构,并定义其中将包含哪些数据。还包括轻松获取数据的方法。

private class myObject {
     private String name;
     private String realName;

     //The constructor, so you can set the data when creating the Object.
     public myObject (String disp_name, String real_name) {
         name = disp_name;
         realName = real_name;
     }

     //Getter methods, to get the data.
     public String getRealName() {return realName;}
     public String getDisplayName() {return name;}
}

您的代码:

private Object get_user_det() {
    myObject o;  //Declare it, so it can be returned.
    ...
    String disp_name = nPost.get("disp_name").toString();
    String real_name = nPost.get("real_name").toString();

    o = new myObject(disp_name, real_name); //create it and set the data.
    ...
    return myobject; //return the new Object with the data.
}

从对象中获取数据:

myObject o = get_user_det(); //Call the metod which return our Object.
String realName = o.getRealName(); //Get the data from the Object.
String displayName = o.getDisplayName;

在您的情况下,使用字符串数组会容易得多。

希望这会有所帮助。

【讨论】:

    【解决方案2】:

    如果您在代码中添加一些printlns,可能最容易看到发生了什么:

    private Object get_user_det() {
        Firebase f_user = new Firebase("https://myapp.firebaseio.com/User/");
        System.out.println("Adding listener");
        f_user.addListenerForSingleValueEvent(new ValueEventListener(){
            @Override
            public void onDataChange(DataSnapshot snap_user) {
                System.out.println("Data received");
            }
            @Override
            public void onCancelled(FirebaseError arg0) {
                // TODO Auto-generated method stub                  
            }
        });
        System.out.println("Returning");
        return null; //NB: I NEED TO RETURN THE OBJECT HERE.
    }
    

    如果你执行这段代码,你会看到它记录:

    Adding listener
    Returning
    Data received
    

    这很可能不是您所期望的。但是,如果您阅读下面的解释,希望它是有意义的。

    异步加载

    当你注册你的听众时:

     f_user.addListenerForSingleValueEvent(new ValueEventListener(){
    

    您告诉 Firebase开始 监听事件。它关闭并开始从服务器检索数据。

    由于检索数据可能需要一些时间,因此它会异步执行此检索,以免您的线程被阻塞。完全检索数据后,Firebase 会在您的侦听器中调用 onDataChange 方法。

    在您开始收听和调用onDataChange 之间,您的代码会继续执行。所以没有办法返回异步加载的数据,因为当你的函数返回时,数据还没有加载。

    解决方案

    免责声明:我不是用 Java 解决这个问题的专家,所以我的解决方案可能存在问题。如果^H^H发现有,请在cmets中报告。

    我知道该问题的三种可能解决方案:

    1. 强制代码等待数据返回
    2. 返回一个在某个时候将包含数据的 Future
    3. 将回调传递给get_user_det,并在数据可用时调用该函数

    您可能会倾向于选择选项 1,因为它与您加载数据的心理模式最匹配。虽然这不一定是错误的,但请记住,异步加载是有充分理由的。现在可能值得接受“学习如何处理异步”的惩罚。

    我不会为所有解决方案编写示例,而是参考一些相关问题:

    【讨论】:

      【解决方案3】:

      工作原理:

      Firebase 使用反射构建 JSON 树对象以保存到数据库。当您检索此 JSON 树时,您可以将其转换回您的原始对象。就像序列化和反序列化一样。这意味着当您尝试像您一样“重建”您的对象时,您不需要处理键和值。都可以这样完成:

      YourObject 对象 = (YourObject) dataSnapshot.getValue(YourObject.class);

      注意getValue() 中的YourObject.class。这告诉 firebase 通过此类进行反射并使用 dataSnapshot 找到适当的访问器。


      怎么做

      确保您的对象具有:

      1. 访问器 为所有字段提供适当的 getter 和 setter -(如果您不想保存特定字段,请使用 @JsonIgnore 注释)
      2. 空构造函数。您的对象必须提供一个完全不修改自身的构造函数。

      你的对象应该是什么样子:

      public class YourObject {
      
           private String displayName;
           private String realName;   
      
           public YourObject() { /*Empty constructor needed for Firebase */ }
      
           // Accessors
      
           public void setRealName(String realName){
              this.realName = realName;
           }
      
           public String getRealName(){
              return this.realName;
           }
      
           public String getDisplayName(){
              return this.displayName;
           }
      
           public void setDisplayName(String displayName){
              this.displayName = displayName;
           } 
       }
      

      然后,在任何 firebase 回调中,您只需将 DataSnapshot 投射到您的对象中:

      public void onDataChange(DataSnapshot snap_user) {
            YourObject object = new Object;
            if(snap_user.getValue() != null) {
              try {
                 object = (YourObject) snap_user.getValue(YourObject.class); <-- Improtant!!!
              } catch(ClassCastException ex) {
                 ex.printStackTrace();
              }
            }
         return object;
      }
      

      还有

      您似乎正在检索许多对象。执行此操作时,我发现最好使用 onChildEventListener,然后对于该节点中的 每个 YourObjects,将调用 onChildAdded(DataSnapshot ds, String previousChild);

      【讨论】:

        猜你喜欢
        • 2019-01-29
        • 2015-06-06
        • 2014-05-27
        • 2014-05-22
        • 2017-03-06
        • 2011-01-25
        • 1970-01-01
        • 1970-01-01
        • 2010-10-22
        相关资源
        最近更新 更多