我正在尝试使用从侦听器获取的用于单事件调用的方法返回数据。但是,看起来我要返回的对象是在实际的return语句之后填充的。我知道获取数据快照的调用是异步的,这就是为什么这种情况发生的原因。如何避免这种情况?我已经尝试过信号量和原子布尔,但是它似乎锁定了我的应用程序。这是有问题的代码。
static User getUser(String uid){
/**** created final object here for returning ****/
final User returnUser = new User();
Firebase userRef = new Firebase("<firebase-url>/users/"+uid+"/");
userRef.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
Log.d("MT", "attempting to instantiate user");
User tempUser = dataSnapshot.getValue(User.class);
/**** preparing object for return ****/
returnUser.setNickname(tempUser.getNickname());
returnUser.setAge(tempUser.getAge());
returnUser.setEmail(tempUser.getEmail());
returnUser.setHeight(tempUser.getHeight());
returnUser.setSex(tempUser.getSex());
returnUser.setWeight(tempUser.getWeight());
//This logs actual information
Log.d("MT", returnUser.getNickname() + " =======INSTANTIATED=======.");
Log.d("MT", returnUser.getEmail());
Log.d("MT", new Double(returnUser.getAge()).toString());
Log.d("MT", new Double(returnUser.getHeight()).toString());
Log.d("MT", returnUser.getSex());
Log.d("MT", new Double(returnUser.getWeight()).toString());
}
@Override
public void onCancelled(FirebaseError firebaseError) {
Log.d("MT", "Something went wrong.");
}
});
Log.d("MT", returnUser.getNickname()); //This logs an empty string.
return returnUser;
}
注意:我已经尝试将Atomic布尔值设置为false,然后在侦听器中设置为true,然后在返回之前设置一会儿(boolean == false),但这会导致应用程序锁定。
您尝试做的是使Firebase同步。
这可能是可行的,但这是一个非常糟糕的主意。冒着在主线程上进行网络操作的风险。一种使Android非常脾气暴躁的模式。请参阅他们在单独的线程上进行网络工作的一般指导。
因此,确定在另一个线程上进行网络操作是一件好事,对于您来说,我是个好消息。Firebase已经自动执行此操作!指定回调,就像在中一样AsyncTask
。
更改您的getter以接受回调作为参数。
public void getUser(String uid, AwesomeCallback callback){
Firebase userRef = new Firebase("<firebase-url>/users/"+uid+"/");
userRef.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
Log.d("MT", "attempting to instantiate user");
User returnUser = new User();
User tempUser = dataSnapshot.getValue(User.class);
/**** preparing object for return ****/
returnUser.setNickname(tempUser.getNickname());
returnUser.setAge(tempUser.getAge());
returnUser.setEmail(tempUser.getEmail());
returnUser.setHeight(tempUser.getHeight());
returnUser.setSex(tempUser.getSex());
returnUser.setWeight(tempUser.getWeight());
//This logs actual information
Log.d("MT", returnUser.getNickname() + " =======INSTANTIATED=======.");
Log.d("MT", returnUser.getEmail());
Log.d("MT", new Double(returnUser.getAge()).toString());
Log.d("MT", new Double(returnUser.getHeight()).toString());
Log.d("MT", returnUser.getSex());
Log.d("MT", new Double(returnUser.getWeight()).toString());
callback.doCallback(returnUser);
}
@Override
public void onCancelled(FirebaseError firebaseError) {
Log.d("MT", "Something went wrong.");
}
});
}
然后,通过回调函数完成工作
public class SomeAwesomeActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
someObject.getUser("uid123", new AwesomeCallback() {
@Override
public void doCallback(User user) {
// Do cool stuff with that user object here
}
});
}
}
如果您过去没有做过很多回调编程,那会有些奇怪,并且需要一些时间来习惯它。但是,一旦您掌握了它,Android开发就会更加顺利。Android SDK中内置的许多构造都依赖于此模式。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句