我在android中使用google Firebase数据库。我需要两个从数据库中获取两组数据 - userInfo和assignmentInfo。然后我需要将它们组合起来并在回收站视图中显示数据。解决这个问题的最佳方法是什么?由于获取数据是异步的,因此变得混乱。
我能想到的一种方法是,如果其他功能已完成,请检查两个异步功能是否成功。如果是这样,获取其数据,组合并初始化适配器。这是最好的方法吗?
答案 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获取数据。获取第一部分的数据后,启动第二部分的获取操作,以便更好地控制代码。
我刚刚提出了一些想法,选择任何适合你的想法。希望有所帮助!