两次异步操作后更新UI

时间:2018-04-19 16:51:52

标签: java android asynchronous firebase-realtime-database

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

我能想到的一种方法是,如果其他功能已完成,请检查两个异步功能是否成功。如果是这样,获取其数据,组合并初始化适配器。这是最好的方法吗?

3 个答案:

答案 0 :(得分:1)

当我在用户登录应用程序之前必须从数据库下载某些内容时,我已经解决了这种问题,我解决了这个问题。

要使用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 asynctasks来解决这个问题很容易,当其中一个asynctasks完成mObsInt等于1时,如果另一个asyncTask完成{{1}将是mObsInt,然后你的mObsInt++将等于2,监听器将等待值,然后当值与你的if语句匹配时,你要做你想做的事情mObsInt方法

现在,只是在你的asynctasks中放入你的onPostExecute()方法这一行

onCreate

所以如果第一次异步完成,mObsint == 1,如果第二次完成mObsInt == 2,然后你在onCreate方法中处理你想要做的事情

希望这对你有所帮助,它帮助了我

您可以在此文档中获取更多信息:https://developer.android.com/reference/android/databinding/ObservableInt.html

快乐的编码!

答案 1 :(得分:0)

我在没有Rx / Coroutines /其他东西的项目中使用的最简单的方法。只需创建AtomicInteger即可。初始化它的值等于异步操作的数量。然后在异步函数的每次回调中调用:

if(counter.decrementAndGet == 0) { your_final_action}

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

答案 2 :(得分:0)

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

如果您考虑自己构建一个线程安全的实现,那也不是那么困难。您可能只考虑使用Synchronized函数来更新您要保留的标志,以检测是否同时获取来自firebase的两个数据。

但是,我建议您使用LocalBroadcastReceiver完成实施。哪个更容易实现,这是一个Android解决方案。虽然可能还有其他几种方法也很棒,但我认为BroadcastReceiver的实施将完全符合您的目的。

您可以查看this answer以检查BroadcastReceiver的实施情况。当从firebase获取数据的第一部分时,发送要由BroadcastReceiver中的Activity接收的广播并设置标志值,例如,1。然后当收到第二部分时,你必须通过发送广告来获取来自firebase的响应,再次将值设置为2。然后,当找到值2时,这意味着两个操作都已完成,现在您可以合并这两个列表。

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

我刚刚提出了一些想法,选择任何适合你的想法。希望有所帮助!