返回一个Android对象 [英] return an object Android

查看:152
本文介绍了返回一个Android对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



这是声明;

  Object user_det = get_user_det(); 

以下是功能代码:

  private Object get_user_det(){
Firebase f_user = new Firebase(https://myapp.firebaseio.com/User/);
f_user.addListenerForSingleValueEvent(新ValueEventListener(){
@覆盖
公共无效onDataChange(DataSnapshot snap_user){
// TODO自动生成方法存根
可迭代< DataSnapshot> ; RS = snap_user.getChildren();
迭代< DataSnapshot> IRS = rs.iterator();
长allNum2 = snap_user.getChildrenCount();
INT maxNum2 =(int)的allNum2;
int count_user = 1;
while(irs.hasNext())
{
if(count_user< = maxNum2)
{
Firebase user_data =新火力地堡( https://myapp.firebaseio.com/);
的authData的authData = user_data.getAuth();
地图<字符串,对象> nPost =(地图<字符串,对象>) irs.next()。getValue();

St ring db_email = nPost.get(email_addr)。toString(); ($ authData!= null){
String usr_email = authData.getProviderData()。get(email)。toString();

if
如果(usr_email.equals(db_email))
{
// NB:我要添加以下到OBJECT
字符串disp_name = nPost.get( disp_name)的ToString();
String real_name = nPost.get(real_name)。toString();
}

} else {
System.out.println(Failed);
}
}
count_user ++;

$ b @Override
public void onCancelled(FirebaseError arg0){
// TODO自动生成的方法存根

}
});
返回null; //注意:我需要在此回复对象。





$ b我希望返回字符串disp_name和real_name,但它们在addListenerForSingleValueEvent中,所以我怎样才能把它们返回给函数。


我在代码中写了NB,我需要帮助


感谢您的宝贵时间。

解决方案

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

  private Object get_user_det(){
Firebase f_user = new Firebase(https://myapp.firebaseio.com/User/);
System.out.println(Adding listener);
f_user.addListenerForSingleValueEvent(新ValueEventListener(){
@覆盖
公共无效onDataChange(DataSnapshot snap_user){
的System.out.println( 数据接收);
}
@Override
public void onCancelled(FirebaseError arg0){
// TODO自动生成的方法存根
}
});
System.out.println(Returning);
返回null; //注意:我需要在此回复对象。





$ b

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

 添加监听器
返回
收到的数据

很可能,这不是您所期望的。但希望如果你阅读我的解释是有道理的。



异步加载



当你注册你的监听器:

  f_user.addListenerForSingleValueEvent(new ValueEventListener(){

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



由于检索数据可能需要一些时间,因此它会异步执行此检索,以便您的线程不被阻塞。一旦数据完全检索,Firebase将调用 onDataChange

在开始监听的时间和调用 onDataChange 的时间之间,您的代码将继续执行,因此无法返回异步加载的数据,因为当函数返回时,数据尚未加载。 / h2>

声明:我不是ex在解决这个问题在Java中,所以有可能是我的解决方案的问题。如果^ H ^您发现任何问题,请在评论中报告。



我知道三个可能的解决方案: b
$ b


  1. 强制代码等待数据返回

  2. 返回一个Future,在某个时刻将包含数据

  3. 将回调函数传递给 get_user_det ,并在数据可用时调用该函数

您可能会想要选择选项1,因为它与您的加载数据的心理模式最接近。虽然这不一定是错误的,但要记住加载是异步完成的。现在可能值得采取学习如何处理异步性的惩罚。

不是写所有解决方案的例子,而是引用一些相关的问题:




I want to return an object with some things in them.

Here is the declaration;

Object user_det = get_user_det();

Here is the function code:

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

I want to return the string disp_name and real_name but they are inside the addListenerForSingleValueEvent, so how do I get them out and return it to the function.

I have wrote "NB" in the code where I need help with.

Thanks for your time.

解决方案

It's probably easiest to see what's going on, if you add some printlns to your code:

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

If you execute this code, you will see that it logs:

Adding listener
Returning
Data received

Most likely, this is not what you expected. But hopefully, it makes sense if you read my explanation below.

Asynchronous loading

When you register your listener:

 f_user.addListenerForSingleValueEvent(new ValueEventListener(){

You tell Firebase to start listening for events. It goes off and starts retrieving the data from the server.

Since retrieving the data may take some time, it does this retrieval asynchronously so that your thread isn't blocked. Once the data is completely retrieved, Firebase calls the onDataChange method in your listener.

Between the time you start listening and the time onDataChange is called, your code continues executing. So there is no way to return data that is loaded asynchronously, because by the time your function returns, the data isn't loaded yet.

Solutions

Disclaimer: I am not an expert at solving this problem in Java, so there may be problems with my solutions. If^H^HWhen you find any, please report them in the comments.

I know of three possible solutions to the problem:

  1. force the code to wait for the data to be returned
  2. return a Future that at some point will contain the data
  3. pass a callback into get_user_det and call that function once the data is available

You will probably be tempted to selected option 1, since it matches most closely with your mental modal of loading data. While this is not necessarily wrong, keep in mind that there is a good reason that the loading is done asynchronously. It might be worth taking the "learning how to deal with asynchronicity" penalty now.

Instead of writing up examples for all solutions, I'll instead refer to some relevant questions:

这篇关于返回一个Android对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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