返回Android对象

时间:2015-03-30 11:57:24

标签: android object return firebase

我想要返回一个包含其中一些内容的对象。

这是宣言;

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中,所以如何将它们取出并将其返回给函数。

  

我写了#34; NB&#34;在我需要帮助的代码中。

感谢您的时间。

3 个答案:

答案 0 :(得分:1)

如果要从java中的方法返回一个对象,请执行以下操作:


Object类: 它包含Object的结构,并定义其中的数据。还包括轻松获取数据的方法。

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;

在您的情况下,使用String数组会更容易。

希望这有帮助。

答案 1 :(得分:1)

如果您在代码中添加一些println,可能最容易看到正在发生的事情:

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 ^如果您发现任何问题,请在评论中报告。

我知道这个问题有三种可能的解决方案:

  1. 强制代码等待数据返回
  2. 返回一个在某些时候将包含数据的未来
  3. 将回调传递到get_user_det并在数据可用后调用该函数
  4. 您可能会想要选择选项1,因为它与您加载数据的心理模式最匹配。虽然这不一定是错误的,但请记住,有一个很好的理由是异步完成加载。可能值得学习如何处理异步性问题&#34;惩罚现在。

    我没有为所有解决方案编写示例,而是提及一些相关问题:

答案 2 :(得分:1)

工作原理:

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

  

YourObject object =(YourObject)dataSnapshot.getValue(YourObject.class);

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


怎么做

确保您的对象有:

  1. 访问者所有字段的适当getter和setter - (如果您不想保存特定字段,则使用@JsonIgnore注释)
  2. 空构造函数。您的对象必须提供一个根本不会自行修改的构造函数。
  3. 您的对象应该是什么样的:

    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然后对该节点中YourObject每个进行调用,onChildAdded(DataSnapshot ds, String previousChild);将被调用。