【问题标题】:Android how to wait for onComplete method to end before proceeding to the next codeAndroid如何在继续下一个代码之前等待onComplete方法结束
【发布时间】:2019-03-29 16:47:01
【问题描述】:

在继续下一步之前,我想从我的 onComplete 函数中获取一个布尔值。

我的问题是,当我的布尔值 (isLoginSucces) 对我的代码至关重要时,当代码到达部分时,它得到的只是错误值,因为 onComplete 函数没有到达它更改布尔值的点。

我尝试了异步函数,但它不起作用,也尝试了 AtomicBoolean,也没有用。

在那之后,我什至放了 Thread.sleep(10000)。在那段时间(10 秒)它肯定改变了值,但也不起作用,仍然是错误的,我不明白。

    private String loginButtonClicked () {

            mAuth.signInWithEmailAndPassword(email, password).addOnCompleteListener(getActivity(), new OnCompleteListener<AuthResult>() {
                @Override
                public void onComplete(@NonNull Task<AuthResult> task) {
                    if (task.isSuccessful()) {
                        ...
                        LoginFragment.this.isLoginSucces = true;
                        Log.d("boolean", "boolean value in onComplete: " + isLoginSucces);
                    } else {
                        ...
                        LoginFragment.this.isLoginSucces = false;
                    }
                }
            });

            //HERE I tried Thread.sleep(10000);
            Log.d("boolean", "boolean value after function: " + isLoginSucces);

            if (LoginFragment.this.isLoginSucces)
                return email;
            else
                return null;

    }

日志输出为:

2019-03-29 18:45:12 D/boolean:函数后的布尔值:false

2019-03-29 18:45:14 D/boolean:onComplete 中的布尔值:true

【问题讨论】:

  • 一般来说你不会。那是一个回调函数。这意味着工作要么在另一个线程上完成,要么在这个线程上但在稍后的时间完成。在某些情况下,您可以安全地这样做,但不是一般情况下。相反,您的代码应该编写为不等待结果。如果这是主要主题,则尤其如此-在这种情况下,它永远不应该等待任何事情。这样做基本上会导致无响应,最坏的情况会导致挂起
  • 但是我需要 onComplete 函数,只有这样才能从 Firebase 获取数据。我不知道其他方式。
  • RIght- 所以使用 onComplete 结果的代码应该进入 onComplete。你不应该等待它被调用。相反,您不应该在调用结果之前使用调用的结果,并在此之前显示加载 UI(如果需要)
  • 是的,我明白你的意思,但我需要它来返回一个值,而且如你所知,onComplete 是 void 类型。无法从中返回任何内容,也无法从变量中检索所需的信息,因为它会很快克服它。
  • 您需要重构代码以调用 onComplete 中的函数,该函数包含调用此方法后运行的所有代码。此方法将是无效的,并且任何需要 String 的内容都在您在 onComplete 中调用的方法中。这是确保结果可供您使用的唯一方法。

标签: java android multithreading


【解决方案1】:
public void methodThatCallsLoginButtonClicked() {
    // code before calling loginButtonClicked 

    loginButtonClicked();

    // nothing else that needs the value from login button clicked should be here
}

public void afterLogin(boolean result) {
    // any code that needs the value of the login callback
}

private void loginButtonClicked () {

        mAuth.signInWithEmailAndPassword(email, password).addOnCompleteListener(getActivity(), new OnCompleteListener<AuthResult>() {
            @Override
            public void onComplete(@NonNull Task<AuthResult> task) {
                afterLogin(task.isSuccessful());
            }
        });

}

【讨论】:

    【解决方案2】:

    声明

    String str_email = ""; 
    

    在代码的顶部。

    在 oncomplete 方法中插入依赖代码,移除 return 语句并更改为:

    private String loginButtonClicked () {
    
                mAuth.signInWithEmailAndPassword(email, password).addOnCompleteListener(getActivity(), new OnCompleteListener<AuthResult>() {
                    @Override
                public void onComplete(@NonNull Task<AuthResult> task) {
                    if (task.isSuccessful()) {
                        ...
                        LoginFragment.this.isLoginSucces = true;
                        Log.d("boolean", "boolean value in onComplete: " + isLoginSucces);
                    } else {
                        ...
                        LoginFragment.this.isLoginSucces = false;
                    }
    
                   if (LoginFragment.this.isLoginSucces)
                       str_email = email;
                   else
                       str_email = ";
    
            });
    }
    

    编写代码
    if(!str_email.equals("")){
    
    //if str_email is different from ""
    
    
    }
    

    【讨论】:

    • 还是一样的结果,见日志:2019-03-29 19:08:16.423 D/boolean: str value after function: 2019-03-29 19:08:17.570 D/boolean: str value在 onComplete: ainkiwi@gmail.com
    • 仍然在 onComplete 函数之外使用 null 值
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-28
    • 2011-11-01
    • 1970-01-01
    • 2020-04-08
    • 1970-01-01
    相关资源
    最近更新 更多