java– 如何通过方法返回DataSnapshot值?

java– 如何通过方法返回DataSnapshot值?,第1张

概述我对Java没有多少经验.我不确定这个问题是不是很愚蠢,但是我需要从Firebase实时数据库中获取用户名,并且由于此方法返回此名称.所以,我想出了如何获得这个值,但我不明白如何返回它作为这个方法的结果.最好的方法是什么?privateStringgetUserName(Stringuid){databaseRe

我对Java没有多少经验.我不确定这个问题是不是很愚蠢,但是我需要从Firebase实时数据库中获取用户名,并且由于此方法而返回此名称.所以,我想出了如何获得这个值,但我不明白如何返回它作为这个方法的结果.最好的方法是什么?

private String getUsername(String uID) {    databaseReference.child(String.format("users/%s/name", uID))            .addListenerForSingleValueEvent(new ValueEventListener() {        @OverrIDe        public voID onDataChange(DataSnapshot dataSnapshot) {            // How to return this value?            dataSnapshot.getValue(String.class);        }        @OverrIDe        public voID onCancelled(DatabaseError databaseError) {}    });}

解决方法:

这是异步Web API的经典问题.您现在无法返回尚未加载的内容.换句话说,您不能简单地创建一个全局变量并在onDataChange()方法之外使用它,因为它始终为null.这是因为onDataChange()方法被称为异步.根据您的连接速度和状态,可能需要几百毫秒到几秒才能获得数据.

但是,不仅Firebase实时数据库异步加载数据,几乎所有现代其他Web API都会这样做,因为它可能需要一些时间.因此,不是等待数据(这可能导致用户无响应的应用程序对话框),而是在辅助线程上加载数据时,主应用程序代码会继续.然后,当数据可用时,将调用onDataChange()方法并可以使用该数据.换句话说,在调用onDataChange()方法时,您的数据尚未加载.

让我们举一个例子,在代码中放置一些日志语句,以便更清楚地了解正在发生的事情.

private String getUsername(String uID) {    Log.d("TAG", "Before attaching the Listener!");    databaseReference.child(String.format("users/%s/name", uID)).addListenerForSingleValueEvent(new ValueEventListener() {        @OverrIDe        public voID onDataChange(DataSnapshot dataSnapshot) {            // How to return this value?            dataSnapshot.getValue(String.class);            Log.d("TAG", "InsIDe onDataChange() method!");        }        @OverrIDe        public voID onCancelled(DatabaseError databaseError) {}    });    Log.d("TAG", "After attaching the Listener!");}

如果我们运行此代码将输出,输出将是:

Before attaching the Listener!

After attaching the Listener!

InsIDe onDataChange() method!

这可能不是您所期望的,但它解释了为什么返回时数据为空的原因.

大多数开发人员的初始响应是尝试“修复”这种异步行为,我个人建议不要这样做.网络是异步的,越早接受,您就越早了解如何通过现代Web API提高工作效率.

我发现为这个异步范例重构问题最容易.我没有说“首先获取数据,然后记录它”,而是将问题框定为“开始获取数据.加载数据时,记录它”.这意味着任何需要数据的代码必须位于onDataChange()方法内部或从内部调用,如下所示:

databaseReference.child(String.format("users/%s/name", uID)).addListenerForSingleValueEvent(new ValueEventListener() {    @OverrIDe    public voID onDataChange(DataSnapshot dataSnapshot) {        // How to return this value?        if(dataSnapshot != null) {            System.out.println(dataSnapshot.getValue(String.class));        }    }    @OverrIDe    public voID onCancelled(DatabaseError databaseError) {}});

如果你想在外面使用它,还有另一种方法.您需要创建自己的回调以等待Firebase返回数据.要实现这一点,首先需要创建一个这样的接口:

public interface MyCallback {    voID onCallback(String value);}

然后,您需要创建一个实际从数据库获取数据的方法.此方法应如下所示:

public voID readData(MyCallback myCallback) {    databaseReference.child(String.format("users/%s/name", uID)).addListenerForSingleValueEvent(new ValueEventListener() {        @OverrIDe        public voID onDataChange(DataSnapshot dataSnapshot) {            String value = dataSnapshot.getValue(String.class);            myCallback.onCallback(value);        }        @OverrIDe        public voID onCancelled(DatabaseError databaseError) {}    });}

最后,只需调用readData()方法并将MyCallback接口的实例作为参数传递到您需要的地方,如下所示:

readData(new MyCallback() {    @OverrIDe    public voID onCallback(String value) {        Log.d("TAG", value);    }});

这是在onDataChange()方法之外使用该值的唯一方法.有关更多信息,您还可以查看此video.

总结

以上是内存溢出为你收集整理的java – 如何通过方法返回DataSnapshot值?全部内容,希望文章能够帮你解决java – 如何通过方法返回DataSnapshot值?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/1104573.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-28
下一篇2022-05-28

发表评论

登录后才能评论

评论列表(0条)

    保存