返回一个对象 Android

Posted

技术标签:

【中文标题】返回一个对象 Android【英文标题】:return an object 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数组就可以了。 【参考方案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中报告。

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

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

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

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

Retrieving data from firebase returning NULL(使用方法3的答案) Is waiting for return, ok? Java wait() & notify() vs android wait() & notify()(来自采用方法 1 的用户提出的问题)

【讨论】:

【参考方案3】:

工作原理:

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

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

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


怎么做

确保您的对象具有:

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

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

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

【讨论】:

以上是关于返回一个对象 Android的主要内容,如果未能解决你的问题,请参考以下文章

AndroidAndroid动态代理为SurfaceHolder添加Hook

AndroidAndroid如何一进入一个activity就弹出输入法键盘

Androidandroid常用工具类。

AndroidAndroid应用安装失败及无法打开

AndroidAndroid 多任务配置

AndroidAndroid六种布局详解