Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/216.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 两次异步操作后更新UI_Java_Android_Asynchronous_Firebase Realtime Database - Fatal编程技术网

Java 两次异步操作后更新UI

Java 两次异步操作后更新UI,java,android,asynchronous,firebase-realtime-database,Java,Android,Asynchronous,Firebase Realtime Database,我正在android中使用google Firebase数据库。我需要两个从数据库中获取两组数据-userInfo和assignmentInfo。然后我需要将它们组合起来,并在回收器视图中显示数据。最好的方法是什么?由于数据的获取是异步的,这就变得很混乱 我可以想到的一种方法是,如果另一个异步函数已经完成,则检查这两个异步函数是否成功。如果是,则获取其数据,合并并初始化适配器。这是最好的方法吗?这是我在没有Rx/协同程序/其他东西的项目中使用的最简单的方法。只需创建原子整数。使用等于异步操作数的

我正在android中使用google Firebase数据库。我需要两个从数据库中获取两组数据-userInfo和assignmentInfo。然后我需要将它们组合起来,并在回收器视图中显示数据。最好的方法是什么?由于数据的获取是异步的,这就变得很混乱


我可以想到的一种方法是,如果另一个异步函数已经完成,则检查这两个异步函数是否成功。如果是,则获取其数据,合并并初始化适配器。这是最好的方法吗?

这是我在没有Rx/协同程序/其他东西的项目中使用的最简单的方法。只需创建原子整数。使用等于异步操作数的值初始化它。然后在异步函数的每个回调中调用以下内容:

ifcounter.decrementAndGet==0{您的最终操作}


如果您需要我前面提到的其他方法的帮助,请随时询问我。

这可以通过使用一个简单的变量来实现,该变量将递增,或者如果两个数据都可以合并并从Firebase成功返回,则将保留一个标志。但是,这既不是最好的方法,也不会一直有效,因为如果两个异步线程同时尝试更新标志,则可能会失败。然后,对于上面给出的实现,只有在您能够使整个操作线程安全的情况下,它才会起作用

如果你考虑自己建立一个线程安全的实现,那也不难。你可以考虑使用一个同步函数,它将更新你所保存的标志,以检测是否从FialBASE获取两个数据。p> 但是,我建议使用LocalBroadcastReceiver完成您的实现。这是一个更容易实现的Android解决方案。虽然可能还有其他几种方法也很好,但我认为使用BroadcastReceiver实现将完全满足您的目的

您可以检查BroadcastReceiver的实现。当从firebase获取数据的第一部分时,发送广播以供BroadcastReceiver在活动中接收,并设置一个标志值,例如1。然后,当接收到第二部分时,您必须再次将值设置为2,只需在从firebase获得响应时发送广播即可。然后,当值为2时,这意味着这两个操作都已完成,现在可以合并这两个列表

<>为了避免整个线程安全和故障安全编码开销,您可以考虑同步地从FielBASE获取数据。获取第一部分的数据后,启动第二部分的获取操作,以便更好地控制代码


我刚刚提出了一些想法,随便挑一个适合你的。希望有帮助

我已经解决了这样的问题,在用户登录应用程序之前,我必须从数据库下载一些东西,通过这个我解决了这个问题

要使用ObservableInteger,您可以这样做

先申报

private ObservableInteger mObsInt;
然后在onCreate中,您将有一个侦听器等待mObsInt的值更改,在这些值更改后,您可以做任何您想做的事情

//Listener
        mObsInt = new ObservableInteger();
        mObsInt.set(0);

        mObsInt.setOnIntegerChangeListener(new OnIntegerChangeListener()
        {
            @Override
            public void onIntegerChanged(int newValue)
            {
                if (mObsInt.get()==1)
                   //Do something if the first asyncTask finishes
                if (mObsInt.get()==2){
                   //Do something if the second asyncTask finishes, in this case i just go to another activity when both asyncTasks finish
                    Intent mainIntent = new Intent().setClass(LoginActivity.this, Principal.class);
                    startActivity(mainIntent);
                    finish();
                }
            }
        });
那么,它是如何工作的呢

ObservableInteger将在变量mObsInt中查找更改,因此假设mObsInt等于1,它将做一些事情,如果等于2,它将做另一件事情,因此,用2个异步任务解决这个问题很容易,当其中一个异步任务完成时,mObsInt将等于1,如果另一个异步任务完成,那么mObsInt将是mObsInt++,然后您的mObsInt将等于2,侦听器将等待值,然后在值与onCreate方法的if station匹配时执行您想要执行的操作

现在,在asynctasks中,将onPostExecute方法放在这一行

mObsInt.set(mObsInt.get()+1);
因此,如果第一个异步finish,mObsint==1,如果第二个finish mObsint==2,然后在onCreate方法中处理您想要做的事情

希望这对你有帮助,对我有帮助

您可以通过此文档获取更多信息:


快乐编码

您在项目中使用Rx吗?不,fire base数据获取是异步的。您看过ObservableInteger吗?我确实用它解决了这类问题是的。因为您使用的是原子。原子与同步方法/锁相比非常轻巧和快速