我创建了一个AsyncTask
来处理唱歌。问题是 Firebase 方法signInWithEmailAndPassword
是在doInBackground
返回值后完成的。我不想onPostExecute(Boolean task)
响应登录任务是否成功,但是当我检查日志消息时,我可以看到onPostExecute()
在onComplete()
之前完成。onComplete()
和doInBackground()
完成后,我该如何制作onPostExecute()
。
日志消息:
01-07 12:25:43.775 4046-4241/mk.capitalria.jusufi.riaposdeveloper V/SignInActivity: doInBackground() return type is false
01-07 12:25:43.785 4046-4046/mk.capitalria.jusufi.riaposdeveloper V/SignInActivity: onPostExecute() task is false
01-07 12:25:44.965 4046-4046/mk.capitalria.jusufi.riaposdeveloper V/SignInActivity: onComplete task is successful: true
01-07 12:25:44.965 4046-4046/mk.capitalria.jusufi.riaposdeveloper V/SignInActivity: onComplete task is complete: true
AsyncTask 类:
public class LoginTask extends AsyncTask<String, Void, Boolean> {
boolean isSuccessful;
boolean isComplete;
FirebaseAuth firebaseAuth;
@Override
protected void onPreExecute() {
super.onPreExecute();
firebaseAuth = FirebaseAuth.getInstance();
signInLayout.setVisibility(View.GONE);
sinInTask.setVisibility(View.VISIBLE);
}
@Override
protected Boolean doInBackground(String... strings) {
final String email = strings[0];
final String password = strings[1];
firebaseAuth.signInWithEmailAndPassword(email, password).
addOnCompleteListener(new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
isSuccessful = task.isSuccessful();
isComplete = task.isComplete();
Log.v(TAG, "onComplete task is successful: " + isSuccessful);
Log.v(TAG, "onComplete task is complete: " + isComplete);
}
});
Log.v(TAG, "doInBackground() return type is " + (isSuccessful && isComplete));
return isComplete && isSuccessful;
}
@Override
protected void onPostExecute(Boolean task) {
super.onPostExecute(task);
Log.v(TAG, "onPostExcecute task is: " + task);
if (!task) {
sinInTask.setVisibility(View.GONE);
signInLayout.setVisibility(View.VISIBLE);
Toast.makeText(SignInActivity.this, "Authentication failed.",
Toast.LENGTH_LONG).show();
} else {
Intent intent = new Intent(SignInActivity.this, MainActivity.class);
startActivity(intent);
finish();
}
}
}
你不应该在这里使用 AsyncTask。Firebase 以异步方式执行 signInWithEmailAndPassword。当操作结束时,它会调用 onComplete,以便将 onPostExecute 中的所有代码移动到 onComplete。
对firebaseAuth.signInWithEmailAndPassword()
的调用已经是异步的,没有必要将其包装在AsyncTask
中。 与其在onPostExecute
中执行操作,不如在onComplete
方法中执行操作。
如前所述,您真的不需要在这里使用 AsyncTask firebaseAuth.signInWithEmailAndPassword()
因为它是非阻塞方法。这意味着您的代码不是逐步执行的,而是在 2 个不同的Thread
中执行的。这就是为什么您首先获得onPostExecute
,然后在Firebase
响应时onComplete
打印到日志中。
如果你真的想使用AsyncTask
你必须等待signInWithEmailAndPassword
返回一些值,可以通过以下方式完成。
public class LoginTask extends AsyncTask<String, Void, Boolean> {
boolean isSuccessful;
boolean isComplete;
FirebaseAuth firebaseAuth;
final ReentrantLock loginLock = new ReentrantLock();
...
@Override
protected Boolean doInBackground(String... strings) {
...
firebaseAuth.signInWithEmailAndPassword(email, password)
.addOnCompleteListener(new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
isSuccessful = task.isSuccessful();
isComplete = task.isComplete();
Log.v(TAG, "onComplete task is successful: " + isSuccessful);
Log.v(TAG, "onComplete task is complete: " + isComplete);
loginLock.unlock()
}
})
.addOnFailureListener(new OnFailureListener {
@Override
public void onFailure(Exception e) {
loginLock.unlock();
}
});
loginLock.lock();
Log.v(TAG, "doInBackground() return type is " + (isSuccessful && isComplete));
return isComplete && isSuccessful;
}
...
}
@Override
protected void onPostExecute(Boolean task) {
super.onPostExecute(task);
Log.v(TAG, "onPostExcecute task is: " + task);
firebaseAuth.signInWithEmailAndPassword(email, password).
addOnCompleteListener(new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
isSuccessful = task.isSuccessful();
isComplete = task.isComplete();
Log.v(TAG, "onComplete task is successful: " + isSuccessful);
Log.v(TAG, "onComplete task is complete: " + isComplete);
task=isComplete && isSuccessful;
if (!task) {
sinInTask.setVisibility(View.GONE);
signInLayout.setVisibility(View.VISIBLE);
Toast.makeText(SignInActivity.this, "Authentication failed.",
Toast.LENGTH_LONG).show();
} else {
Intent intent = new Intent(SignInActivity.this, MainActivity.class);
startActivity(intent);
finish();
}
}
});
}
将firebaseAuth.signInWithEmailAndPassword
添加到onPostExecute
因为在doInBackground方法中,控件不会等待调用onComplete
。 因此,如果您希望在 onComplete 响应之后执行onPost
代码,请像上面一样更改您的onPost
。
不需要 AsyncTask。Firebase的createUserWithEmailAndPassword已经异步工作了。您可以在 OnCompleteListener 的 onComplete 函数中执行所有操作。下面是可用于 onComplete 并删除 AsyncTask 的代码。
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
Intent intent = new Intent(SignInActivity.this, MainActivity.class);
startActivity(intent);
finish();
} else {
sinInTask.setVisibility(View.GONE);
signInLayout.setVisibility(View.VISIBLE);
Toast.makeText(SignInActivity.this, "Authentication failed.",
Toast.LENGTH_LONG).show();
}
}