在我的Android应用程序中,我创建了一个包含ListView
的活动,该活动填充了Firebase数据库中的数据。
数据库结构的JSON树如下:
{
"companies" : {
"companyX" : {
"address" : "50th avenue, NY",
"name" : "Spare-Tools Ltd."
},
"companyZ" : {
"address" : "50th Broadway, NY",
"name" : "Burgers and Burgers"
}
},
"company-requests" : {
"companyX" : {
"req1" : true
"req2" : true
}
},
"requests" : {
"req1" : {
"destination" : "Upper Tooting 122, Bronx",
"origin" : "Philadelphia",
"time" : "1473593287",
...
}
"req2" : {
...
}
}
}
我想使用ListView
节点的请求列表填充requests
。但我首先需要知道属于特定公司的所有请求,因此我首先转到company-requests
节点并检索属于特定公司的所有请求密钥。
我面临的问题是在数据库的最终数据到达之前创建了ListView
:
public class RequestsListActivity extends AppCompatActivity {
private ListView rListView;
DatabaseReference rootNode = FirebaseDatabase.getInstance().getReference();
@Override
protected void onCreate(Bundle savedInstanceState) {
...
rListView = (ListView) findViewById(R.id.result_list_view);
//First I retrieve all the requests of a specific company
DatabaseReference companyRequests = rootNode.child("company-requests/companyX");
companyRequests.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
//Then I retrieve all the keys of these requests
...
while (iterator.hasNext()) {
String key = iterator.next().getKey();
//For each key I retrieve its details from the requests node
DatabaseReference currRequest = rootNode.child("requests/" + key);
currRequest.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
String time;
time = (String) dataSnapshot.child("time").getValue();
Request request = new Request(time);
allRequests.add(request);
}
...onCancelled...
});
}
//THIS CODE IS EXECUTED TO EARLY: BEFORE WE HAVE ANY DATA FROM FIREBASE
RequestAdapter adapter = new RequestAdapter(RequestsListActivity.this, allRequests);
rListView.setAdapter(adapter);
}
...onCancelled...
});
}
}
如何插入等待从Firebase加载值的wait
(微调器?)?
答案 0 :(得分:5)
您可以使用简单的计数器来跟踪待处理负载的数量:
RewriteRule ^example/$ http://www.mainsite.com/example.html [R=301,L]
RewriteCond %{HTTP_HOST} ^.*forwardeddomain\.com$ [NC]
RewriteCond %{REQUEST_URI} !^/example/ [NC]
RewriteRule ^ http://www.mainsite.com [R=301,L]
答案 1 :(得分:0)
我使用java.util.concurrent.CountDownLatch
:
在此示例中,将EquityTotalListener
替换为ValueEventListener
的实现。
private void recalculate() {
final AtomicLong sumUpAll = new AtomicLong();
final CountDownLatch cnt = new CountDownLatch(mapUid2GeoLocation.keySet().size());
for (final String uid : mapUid2GeoLocation.keySet()) {
EquityTotalListener el = mapUid2EquityListener.get(uid);
if (el != null) {
if (logger.isDebugEnabled()) {
logger.debug("Listener for " + uid + " already set up");
cnt.countDown();
}
} else {
el = new EquityTotalListener(database.getDatabase(), uid) {
@Override
public void onCancelled(final DatabaseError databaseError) {
super.onCancelled(databaseError);
cnt.countDown();
}
@Override
protected void valueChanged(final String key, final Object value) {
if (value != null) {
sumUpAll.getAndAdd(Long.parseLong(value.toString()));
cnt.countDown();
}
};
}.attach();
mapUid2EquityListener.put(uid, el);
}
}
if (logger.isDebugEnabled()) {
logger.debug("Waitung for countdown..");
}
try {
final boolean allGood = cnt.await(10, TimeUnit.SECONDS);
if (allGood) {
if (logger.isDebugEnabled()) {
logger.debug("Done waiting, " + uid + " owns " + sumUpAll.get() + " equity");
}
} else {
if (logger.isWarnEnabled()) {
logger.warn("Waiting for read operations ran into timeout");
}
}
} catch (final InterruptedException e) {
if (logger.isErrorEnabled()) {
logger.error(e.getLocalizedMessage(), e);
}
}
}