【问题标题】:AsyncTask's doInBackground returns value before method inside is finishedAsyncTask 的 doInBackground 在内部方法完成之前返回值
【发布时间】:2018-01-07 14:30:41
【问题描述】:

我创建了一个AsyncTask 来处理Sing in。问题是Firebase 方法signInWithEmailAndPassworddoInBackground 返回值后完成。我不想让我的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();
            }
        }
    }

【问题讨论】:

    标签: android firebase asynchronous android-asynctask firebase-authentication


    【解决方案1】:

    你不应该在这里使用 AsyncTask。 Firebase 异步执行 signInWithEmailAndPassword。它在操作结束时调用 onComplete,因此 onPostExecute 中的所有代码都可以移动到 onComplete。

    【讨论】:

      【解决方案2】:

      firebaseAuth.signInWithEmailAndPassword() 的调用已经是异步的,无需将其包装在AsyncTask 中。不要在onPostExecute 中执行您的操作,而是在您的onComplete 方法中执行它们。

      【讨论】:

        【解决方案3】:

        如前所述,你真的不需要在这里使用 AsyncTask 因为firebaseAuth.signInWithEmailAndPassword() 是非阻塞方法。这意味着您的代码不是逐步执行的,而是在 2 个不同的Threads 中执行的。这就是为什么你首先得到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;
            }
        
            ...
        }
        

        【讨论】:

          【解决方案4】:
           @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

          【讨论】:

            【解决方案5】:

            这里不需要 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();
                }
            }
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2020-09-28
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2018-02-08
              • 2017-06-07
              • 1970-01-01
              相关资源
              最近更新 更多