【发布时间】:2018-07-13 18:33:25
【问题描述】:
我有一个注册活动,它应该检查 Firebase 实时数据库中是否存在特定节点。如果是,则通知用户,否则继续注册过程。我正在使用 AsyncTask 进行检查,但问题是当 AsyncTask 返回 value 时,我的主线程已经执行了其余部分。我正在使用 AsyncTask.execute().get() 来获取应该暂停主线程但它不起作用的值。
注册活动
int userRegistered;
firebaseDatabase = FirebaseDatabase.getInstance();
databaseReference = firebaseDatabase.getReference("students");
ProgressDialog progressDialog =
ProgressDialog.show(context_signup,"Registering","Wait");
Log.d("signup","DB_CHECKER_STARTING");
try{
DatabaseCheckTask databaseCheckTask = new DatabaseCheckTask();
userRegistered = databaseCheckTask.execute(roll_no).get();
}
catch (InterruptedException | ExecutionException e){
userRegistered = 0;
}
switch (userRegistered){
case 1:
Log.d("signup","SIGNUP");
SignUpTask signUpTask = new SignUpTask();
signUpTask.execute(first_name,last_name,roll_no,phone_no,serial);
sharedPreferences.edit().putBoolean(Constants.FIRST_RUN,false).apply();
break;
case 2:
Log.d("signup","NOSIGNUP");
Toast.makeText(context_signup,"Student with this Roll number is
registered already..",Toast.LENGTH_LONG).show();
break;
case 3:
Log.d("signup","DATABASE_ERROR");
Toast.makeText(context_signup,"Error connecting to database! Please try again after some time.",Toast.LENGTH_LONG).show();
break;
default:
Log.d("signup","DEFAULT_CASE");
Toast.makeText(context_signup,"Slow",Toast.LENGTH_LONG).show();
}
Log.d("signup","DISMISS");
progressDialog.dismiss();
数据库检查任务
public class DatabaseCheckTask extends AsyncTask<String,Integer,Integer>{
int isRegistered;
@Override
protected Integer doInBackground(String... strings) {
DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference("students");
databaseReference.child(strings[0]).addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
if(dataSnapshot.exists()){
Log.d("db_checker","ROLL_MATCHED");
isRegistered = 2;
}
else {
Log.d("db_checker","ROLL_NOT_MATCHED");
isRegistered = 1;
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
Log.d("checker","database error");
isRegistered = 3;
}
});
return isRegistered;
}
}
调试日志
D/signup: DB_CHECKER_STARTING
D/signup: DEFAULT_CASE
D/signup: DISMISS
D/NetworkSecurityConfig: No Network Security Config specified, using platform
default
V/FA: Recording user engagement, ms: 5473
V/FA: Connecting to remote service
V/FA: Activity paused, time: 785707071
D/FA: Logging event (FE): user_engagement(_e),
Bundle[{firebase_event_origin(_o)=auto, engagement_time_msec(_et)=5473,
firebase_screen_class(_sc)=SignUp,
firebase_screen_id(_si)=6624230925954519568}]
V/FA: Connection attempt already in progress
V/FA: onActivityCreated
I/art: Do full code cache collection, code=245KB, data=251KB
I/art: After code cache collection, code=221KB, data=188KB
D/FA: Connected to remote service
V/FA: Processing queued up service tasks: 2
V/FA: onActivityCreated
D/FA: Logging event (FE): screen_view(_vs),
Bundle[{firebase_event_origin(_o)=auto, firebase_previous_class(_pc)=SignUp,
firebase_previous_id(_pi)=6624230925954519568,
firebase_screen_class(_sc)=SignUp,
firebase_screen_id(_si)=6624230925954519569}]
V/FA: Activity resumed, time: 785707379
D/OpenGLRenderer: endAllActiveAnimators on 0x9a56f880 (InsetDrawable) with handle 0x98617430
D/db_checker: ROLL_MATCHED
在调试日志中查看 ROLL_MATCHED 是如何在执行默认情况后实现的,而它应该在进入 switch case 语句之前实现。
【问题讨论】:
-
异步任务将在与主线程不同的单独线程上执行进程,因此主线程将继续执行其代码。因此,您必须在主线程上运行的 AsyncTask 的 onPostExecute() 方法中从 Firebase DB 获取数据后检查特定节点是否存在,有关 AsyncTask 的更多信息,请参阅此链接:stackoverflow.com/a/25647882/6726650
标签: android firebase-realtime-database android-asynctask