AsyncTask的doInBackground在方法完成之前返回值



我创建了一个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();
    }
}

最新更新