我有两节课


OTPBroadcastReceiver-扩展BroadcastReceiver并从新到达的SMS中提取一次性密码(此后称为OTP)的类。
OTPListener-实际上是一个上一个类,其中带有一个回调的类将在收到SMS和提取OTP时执行该回调。


回调具有方法onOTPReceived(long timeReceived, final String otp),该方法由OTPBroadcastReceiver执行,并在消息到达时以long和OTP消息作为String传递给它。

我的OTPListener中有一个内部类,它具有以下成员变量:-

 private class OTPModel {

        long timeReceived = 0L;
        String otp = null;
    }


此类用于存储OTP消息和接收消息的时间。

以下是OTPListener的代码

import android.content.Context;
import android.support.annotation.NonNull;
import android.widget.Toast;

import java.util.List;

class OTPListener {

    private OTPReceivedInternal mOTPReceivedCallback;
    private OTPModel mOTPModel;


    OTPListener(@NonNull final Context context,
                final List<SMSRule> smsRules,
                @NonNull final CustomOTPView.OnOTPReceivedCallback onOTPReceivedCallback) {

        mOTPModel = new OTPModel();

        mOTPReceivedCallback = new OTPReceivedInternal() {

            @Override
            public void onOTPReceived(long timeReceived, String otp) {

                if (mOTPModel.timeReceived == 0L) {

                    mOTPModel.timeReceived = timeReceived;
                    mOTPModel.otp = otp;
                    onOTPReceivedCallback.onOTPReceived(mOTPModel.otp);
                    System.out.println("First execution");
                    System.out.println("Value of mOTPModel.otp:" + mOTPModel.otp);
                    System.out.println(String.valueOf(mOTPModel.timeReceived));
                } else {

                    if (!mOTPModel.otp.equals(otp)) {
                        if (timeReceived > mOTPModel.timeReceived) {
                            Toast.makeText(context, String.valueOf(timeReceived > mOTPModel.timeReceived),Toast.LENGTH_SHORT).show();
                            mOTPModel.timeReceived = timeReceived;
                            onOTPReceivedCallback.onOTPReceived(mOTPModel.otp = otp);
                            System.out.println("After first execution");
                            System.out.println("{{Value of mOTPModel.timeReceived:" + String.valueOf(mOTPModel.timeReceived));
                            System.out.println("Value of mOTPModel.otp:" + String.valueOf(mOTPModel.otp)+"}}");
                        }
                    }
                }
            }
        };


        new OTPBroadcastReceiver(context,smsRules,mOTPReceivedCallback);
    }

    private class OTPModel {

        long timeReceived = 0L;
        String otp = null;
    }

    protected interface OTPReceivedInternal {

        void onOTPReceived(long timeReceived, String otp);

    }


问题是

第一次执行时,

mOTPModel.timeReceivedmOTPModel.otp

即使在以下赋值语句之后也均为空

mOTPModel.timeReceived = timeReceived;
mOTPModel.otp = otp;


而且唯一印在我的Android显示器上的是

System.out.println("First execution");


紧随其后的下两个语句甚至不会执行。

第二次执行时,代码的else部分将被执行,但是这一次它将打印mOTPModel.otpmOTPModel.timeReceived的旧值,随后的执行将继续显示以前的值。

这是怎么了?为什么未正确分配OTPModel类的成员变量?

感谢您的时间!

最佳答案

我相信问题的原因不在您显示的代码范围内。侦听器在哪里实例化?是否创建了多个实例?

分配后,如何确定otptimeReceived为空?也许也可以检查otptimeReceived的传入值(通过调试或使用更多日志记录语句)。

找不到某些System.out.println的事实可能是您的日志记录有问题,或者是某些调试/线程问题使进程停止。

进一步的评论:

private OTPReceivedInternal mOTPReceivedCallback;


令人困惑的字段名称,我将其重命名为otpReceivedInternal。特别是因为还有一个名为onOTPReceivedCallback的构造函数参数。

onOTPReceivedCallback.onOTPReceived(mOTPModel.otp = otp);


令人困惑的成语。我将其拆分为:

mOTPModel.otp = otp;
onOTPReceivedCallback.onOTPReceived(otp);


这更具可读性。

编辑:所以这是我现在建议找出正在发生的变化

        @Override
        public void onOTPReceived(long timeReceived, String otp) {

 // print the received values
 System.out.printf("timeReceived = %s, otp = %s", timeReceived, otp);

            if (mOTPModel.timeReceived == 0L) {

                mOTPModel.timeReceived = timeReceived;
                mOTPModel.otp = otp;
                onOTPReceivedCallback.onOTPReceived(mOTPModel.otp);

 // print the mOTPModel values
 System.out.printf("1: mOTPModel.timeReceived = %s, mOTPModel.otp= %s", mOTPModel.timeReceived, mOTPModel.otp);
 System.out.flush();

                // ... carry on

08-18 18:47