内部类成员变量未正确分配

时间:2016-09-13 09:21:57

标签: java android inner-classes

我有两个班级

  1. OTPBroadcastReceiver - 一个扩展BroadcastReceiver并从新到的短信中提取一次性密码(OTP)的类。
  2. OTPListener - 一个实际启动上一个类的类,其中包含 回调 ,应该在收到短信时执行提取OTP。
  3. 回调有一个方法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.timeReceived&amp; mOTPModel.otp

    即使在以下赋值语句

    之后,

    也都为null

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

    在我的Android监视器上打印的唯一内容是

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

    接下来的两个陈述立即执行。

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

    这里出了什么问题?为什么 OTPModel 类的成员变量没有被正确分配?

    感谢您的时间!

2 个答案:

答案 0 :(得分:1)

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

在分配后,您如何确定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

答案 1 :(得分:0)

我的猜测:检查onOTPReceived(long timeReceived, String otp)本身收到的值。

如果使用(0,null)调用该方法,我不会感到惊讶;因此你的OTPMOdel对象......以初始值(0,null)开始......之后被“更新”为(0,null)。