目前,我正在使用firebase实时数据库。因此,我的数据更改来自另一个线程。因此,我无法控制新数据更新的时间。那我怎么知道何时打电话来刷新我的用户界面呢?
这是我在RecyclerView中删除滑动的实现。
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
int pos = viewHolder.getAdapterPosition();
mListRoute.get(pos).removeRoute();
refreshUI();
}
这是我的Route类
中的removeRoute()方法 public void removeRoute() {
//Delete all the Route Instructions
DatabaseReference mRef = FirebaseDatabase.getInstance().getReference()
.child("Routes")
.child(routeId)
.child("Route Instructions");
mRef.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot routeInstruc : dataSnapshot.getChildren()) {
routeInstruc.getValue(RouteInstructions.class)
.removeRouteInstructions();
}
DatabaseReference mRef2 = FirebaseDatabase.getInstance().getReference()
.child("Routes")
.child(routeId);
mRef2.removeValue();
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
如您所见, onDataChange() 由另一个线程调用。这意味着我不知道何时调用我的 refreshUI() 方法。
我想我可以使用Looper但是我如何在Route类中使用它?
谢谢
答案 0 :(得分:1)
您正在寻找的是回调。
处理异步调用时, 回调几乎是强制性的,因为当您调用异步任务时,基本上是要求工作线程为您工作。
它可能需要1秒,10秒,10分钟等,你无法确定。你可以做的是委托同一个工人线程并告诉她“嘿,当你完成我给你的任务时回复”。
输入回调!
You can check for more documentation regarding callbacks here
假设您使用ValueEventListener
定义了查询query.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot data) {
}
}
你应该做的是有一个回调方法,一旦查询监听器返回一个值(换句话说,执行你的查询时)就会回复。 那么,有一个类似 'onResponseReceivedFromFirebase' 的方法并在回调中实现它
public class MyActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
// Implement your callback here with the parameters you want (for instance, I used a String there)
public void onResponseReceivedFromFirebase(String argument){
Log.d(MyActivity.class,argument);
}
....
query.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot data) {
onResponseReceivedFromFirebase("the response arrived!");
}
}
...
}
@Edit 根据您更新的代码,我将继续以下
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot routeInstruc : dataSnapshot.getChildren()) {
routeInstruc.getValue(RouteInstructions.class)
.removeRouteInstructions();
}
DatabaseReference mRef2 = FirebaseDatabase.getInstance().getReference()
.child("Routes")
.child(routeId);
mRef2.removeValue();
// Implement the callback here
MyActivity.this.onResponseReceivedFromFirebase("We have received a response from dataChanged");
}
@Edit 2:在Frank van Puffelen的评论中,onDataChange方法已在主线程上运行,因此允许您更改UI上的任何元素。
非常重要:如果输出数据的处理负载相当大,您应该将相同的处理传递到另一个线程(例如AsyncTask),以避免使您的应用无响应。
答案 1 :(得分:1)
当Firebase客户端在单独的线程上处理所有网络和磁盘IO时,它会调用主线程上代码的回调。因此,您可以直接从onDataChange()
更新UI,而无需自己担心该主题。
事实上,Firebase文档中的所有示例都会通过其onDataChange()
(或onChild...()
)回调更新用户界面。一个example from the database quickstart:
public void onDataChange(DataSnapshot dataSnapshot) {
// Get Post object and use the values to update the UI
Post post = dataSnapshot.getValue(Post.class);
mAuthorView.setText(post.author);
mTitleView.setText(post.title);
mBodyView.setText(post.body);
}