【问题标题】:why this toast shows up when it should not?为什么这个吐司不应该出现?
【发布时间】:2020-06-12 23:01:20
【问题描述】:

你好

我有一个方法可以验证数据库中是否已经存在电话号码或电子邮件,如果存在,用户将收到一个 toast 说它已经注册,如果没有,它将返回注册活动,它将继续使用代码,

public class VerficatePhone extends AppCompatActivity {
private String mVerficationId,phoneNumber,sentCode;
private User user;
private EditText phoneCodeEditText;
private PhoneAuthProvider.ForceResendingToken mResend;
private Button activate;
private TextView backToSignupText;
private ProgressBar pBar;
private FirebaseAuth mAuth;
private DatabaseReference reff;
private boolean executed =false;



@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_verficate_phone);

    phoneCodeEditText=findViewById(R.id.verificationEditText);
    activate=findViewById(R.id.activate);
    backToSignupText=findViewById(R.id.backToSignupText);
    pBar=findViewById(R.id.progressBar);

    mAuth=FirebaseAuth.getInstance();
    reff= FirebaseDatabase.getInstance().getReference().child("User");


    //getting the user that has been sent from the sign up Activity and the phone number
    if(getIntent().getSerializableExtra("userFromSignUp")!=null)
    {
        user=(User)getIntent().getSerializableExtra("userFromSignUp");
        phoneNumber=user.getPhoneNumber();

    }
    else
    {
        phoneNumber="000";
        Toast.makeText(this,"Error",Toast.LENGTH_SHORT).show();
    }

    if(!executed)
    {
        checkPhoneNumIfExists(user);
        executed =true;
    }

    sendCode(phoneNumber);
}

我的 checkPhoneNumIfExists 方法是这样的

 private void checkPhoneNumIfExists (final User currentUser)
{
    Log.i("checkPhoneNumIfExists method","processing");
     FirebaseDatabase fDb=FirebaseDatabase.getInstance();
        DatabaseReference dbRef=fDb.getReference();
        dbRef.child("User").addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                Iterable<DataSnapshot> children=dataSnapshot.getChildren();
                for(DataSnapshot child:children)
                {
                    if(currentUser!=null && child!=null)
                    {
                        User user= child.getValue(User.class);
                        if(user!=null && !user.getPhoneNumber().isEmpty())
                        {
                            if(currentUser.getPhoneNumber().equals(user.getPhoneNumber()) || currentUser.geteMail().equals(user.geteMail()))
                            {
                                Toast.makeText(VerficatePhone.this,"already registred",Toast.LENGTH_SHORT).show();
                                Intent i =new Intent(VerficatePhone.this,signUpActivity.class);
                                i.putExtra("userFromVerificate",currentUser);
                                i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                                startActivity(i);
                                finish();



                            }
                        }

                    }
                }
            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {

            }
        });

    executed =true;

}

所以这是问题所在,当用户未注册时,它继续使用代码并在 onCreate 方法中执行 sendCode 方法,这将打开一个新活动,但是每当它从 sendCode 方法打开新活动时,checkPhoneNumIfExists 方法的 toast它出现了。

那为什么会发生呢?

【问题讨论】:

  • 你需要澄清你的问题,除了你的代码中有错误之外,很难理解你在问什么。我完全不明白你的代码在做什么?我不知道如何在本地对其进行测试以重现错误?在函数中:onCreate() “执行”在哪里定义?您在 checkPhoneNumIfExists() 中定义了“已执行”,但您从不返回值?你说你不应该导致函数是无效的
  • 我已经修改了代码,希望它能让它更清晰,我的代码工作正常,但是即使用户没有注册,它也会显示 checkPhoneNumIfExists 的祝酒词,谢谢你的耐心,我没有放所有的课,因为它很长
  • onDataChange() 回调是异步的。您的executed=truesendCode() 可能会在onDataChange() 返回之前运行。您应该确保在该回调返回时或之后触发您需要从该回调中获得的任何内容。
  • 谢谢 Sammy,我可以重写 onCallback 方法吗?或者,也许您可​​以告诉我如何以最好的方式做到这一点

标签: java android class methods toast


【解决方案1】:

onDataChange() 是一个异步回调。任何依赖它的数据或函数都应该在回调中被访问或触发。

由于您似乎不打算每次都运行数据库检查,因此我建议您查看 SharedPreferences 以在您离开并返回活动时保留变量。您可以在 onDataChange() 执行时存储 executed 的值,并在 if 语句之前检索 onCreate() 中的值。

@Override
protected void onCreate(Bundle savedInstanceState){
    // ...

    // If you're using SharedPreferences, retrieve the value here

    if(!executed){
        checkDb(user)
    }else{
        // I'm assuming you only want to send the code when executed is true
        // which means that, for this approach, you should call sendCode()
        // again inside of your onDataChange()
        sendCode(phoneNum);
    }
}

private void checkDb(final User currentUser){
    // ...

    myRef.addValueEventListener(new ValueEventListener(){
        @Override
        public void onDataChange(DataSnapshot dataSnapshot){
            for(DataSnapshot snap: dataSnapshot.getChildren()){
                // do something with the data
                // ...
            }

            // This is where you can set the value of a variable 
            // or execute a function that relies upon the data of the callback. 

            // If you're using SharedPreferences, you would store the value here.

            // You may want to call sendCode() again here
        }
    });
}

您可以通过访问https://developer.android.com/training/data-storage/shared-preferences了解有关 SharedPreferences 的信息

【讨论】:

    猜你喜欢
    • 2022-01-18
    • 1970-01-01
    • 2021-05-21
    • 2020-09-11
    • 1970-01-01
    • 2017-05-23
    • 1970-01-01
    • 2010-11-23
    • 1970-01-01
    相关资源
    最近更新 更多