简体   繁体   中英

Android executing an if statement even though it shouldn't ever execute?

Well I simply have no other way to put this I've got a function that looks as follow:

@Override
public void onSensorChanged(SensorEvent event) {
    old_orientation = orientation;
    if(event.sensor == grav) {
        last_grav_reading = event.values;
    } else {
        last_magnet_reading = event.values;
    }
    if (last_grav_reading != null && last_magnet_reading != null) {
        sensorManager.getRotationMatrix(mat_rotation, mat_inclination, last_grav_reading, last_magnet_reading);
        sensorManager.getOrientation(mat_rotation, orientation);
        if (listener != null) {
            listener.onOrientationSensorUpdate(old_orientation, orientation);
        }
    }
}

So the "getRotationMatrix" should only ever execute if both last_magnet_reading and last_grav_reading are non-zero right?

guess again, the line is actually executed (and causes a major crash), a picture showing the case (the selected line is the line the debugger reports being executed and below that you can see the values for each variable):

在此输入图像描述

So.... What's going on? Is the JRE bugged on android? Oh and there is no other function/thread that is ever accessing these variables. Furthermore, it doesn't happen on my main phone (android 5.0.1) but it does happen on my secondary nexus (4.3). (I could "expect" a sensor simply not being there, but that still would violate that if-statement).

EDIT, full class:

public class OrientationTracker implements SensorEventListener, IOrientationTracker {
    private SensorManager sensorManager;
    private Sensor magnet;
    private Sensor grav;
    private float[] last_grav_reading;
    private float[] last_magnet_reading;
    private float[] mat_inclination = new float[9];
    private float[] mat_rotation = new float[9];
    private float[] old_orientation;
    private float[] orientation;
    private boolean isRunning;
    private OrientationUpdateListener listener;


    public OrientationTracker(Context context) {
        sensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
        this.magnet = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
        this.grav =  sensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY);
        this.orientation = new float[]{0,0,0};
        isRunning = false;
        if (this.magnet != null &&this.grav != null){
            // Success! There's a magnetometer.

        }
    }

    public void start(){
        if(isRunning) {
            //Already running, do nothing
            return;
        }
        registerSensors();
        isRunning = true;
    }
    public void start(OrientationUpdateListener listener) {
        start();
        this.listener = listener;
    }
    public void stop() {
        unregisterSensors();
        isRunning = false;
    }


    public void registerSensors() {
        sensorManager.registerListener(this, magnet, SensorManager.SENSOR_DELAY_NORMAL);
        sensorManager.registerListener(this, grav, SensorManager.SENSOR_DELAY_NORMAL);
    }

    public void unregisterSensors() {
        sensorManager.unregisterListener(this);
    }

    @Override
    public void onSensorChanged(SensorEvent event) {
        old_orientation = orientation;
        String t = event.sensor.getName();
        String p = grav.getName();
        if(event.sensor.equals(grav)) {
            last_grav_reading = event.values;
        } else {
            last_magnet_reading = event.values;
        }
        if (last_grav_reading != null && last_magnet_reading != null) {
            sensorManager.getRotationMatrix(mat_rotation, mat_inclination, last_grav_reading, last_magnet_reading);
            sensorManager.getOrientation(mat_rotation, orientation);
            if (listener != null) {
                listener.onOrientationSensorUpdate(old_orientation, orientation);
            }
        }
    }
    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
    }
}

And trace:

"<1> main@830026754464" prio=5 runnable
  java.lang.Thread.State: RUNNABLE
      at com.scoutingstuff.paul.ivossenjacht.OrientationTracker.onSensorChanged(OrientationTracker.java:71)
      at android.hardware.SystemSensorManager$ListenerDelegate$1.handleMessage(SystemSensorManager.java:204)
      at android.os.Handler.dispatchMessage(Handler.java:99)
      at android.os.Looper.loop(Looper.java:137)
      at android.app.ActivityThread.main(ActivityThread.java:5041)
      at java.lang.reflect.Method.invokeNative(Method.java:-1)
      at java.lang.reflect.Method.invoke(Method.java:511)
      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
      at dalvik.system.NativeStart.main(NativeStart.java:-1)

"<12> android.hardware.SystemSensorManager$SensorThread@830035660424" prio=5 runnable
  java.lang.Thread.State: RUNNABLE
     Incompatible thread state: thread not suspended

"<11> GLThread 357@830035646696" prio=5 waiting
  java.lang.Thread.State: WAITING
     Incompatible thread state: thread not suspended

"<10> Binder_2@830035587352" prio=5 runnable
  java.lang.Thread.State: RUNNABLE
     Incompatible thread state: thread not suspended

"<9> Binder_1@830035581424" prio=5 runnable
  java.lang.Thread.State: RUNNABLE
     Incompatible thread state: thread not suspended

"<8> FinalizerWatchdogDaemon@830035565608" daemon prio=5 waiting
  java.lang.Thread.State: WAITING
     Incompatible thread state: thread not suspended

"<7> FinalizerDaemon@830035565176" daemon prio=5 waiting
  java.lang.Thread.State: WAITING
     Incompatible thread state: thread not suspended

"<6> ReferenceQueueDaemon@830035564816" daemon prio=5 waiting
  java.lang.Thread.State: WAITING
     Incompatible thread state: thread not suspended

"<5> Compiler@830035564576" daemon prio=5 waiting
  java.lang.Thread.State: WAITING
     Incompatible thread state: thread not suspended

"<3> Signal Catcher@830035564096" daemon prio=5 waiting
  java.lang.Thread.State: WAITING
     Incompatible thread state: thread not suspended

"<2> GC@830035563872" daemon prio=5 waiting
  java.lang.Thread.State: WAITING
     Incompatible thread state: thread not suspended
   (last_grav_reading != null && last_magnet_reading != null)

is true after you have received a grav event and after you have received a magnet event. there is no code that last_XXX_reading back to null. did you mean

if(event.sensor == grav) {
    last_magnet_reading = null;
    last_grav_reading = event.values;
} else {
    last_grav_reading = null;
    last_magnet_reading = event.values;
}

both sensors are attached to the same listener this

    sensorManager.registerListener(this, magnet, SensorManager.SENSOR_DELAY_NORMAL);
    sensorManager.registerListener(this, grav, SensorManager.SENSOR_DELAY_NORMAL);

First question what returns event.value ? If it returns for eg. array of null's then if statment will allways execute because last_grav_reading != null is allways true.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM