Android 4:从传感器事件监听器启动子活动:同步失败

时间:2012-11-20 06:38:07

标签: android synchronized android-sensors critical-section

如果智能手机是颠倒的,我正尝试从传感器事件监听器启动子活动。我写的初始代码看起来像这样:

public class MySensorListener implements SensorEventListener{

    boolean mIsStarted = false;

    public void start(Context context) {
        mIsStarted = false;
        SensorManager manager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
        manager.registerListener(this, manager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL);
    }

    public void stop(Context context) {
        mIsStarted = false;
        SensorManager manager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
        manager.unregisterListener(this);
    }

    public void onAccuracyChanged(Sensor sensor, int accuracy) {}

    public void onSensorChanged(SensorEvent event) {
        if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
            float z = event.values[2];

            if (z < -8f) {
                if (!mIsStarted) {
                    mIsStarted = true;
                    // start child activity
                }

            } else if (z > -7f) {
                if (mIsStarted) {
                    mIsStarted = false;
                    // stop child activity
                }
            }
        }
    }

}

现在我遇到了问题,Android 4设备启动活动大约三次而不是一次。我认为这是因为onSensorChanged方法在很短的时间内被调用太频繁了。 所以我试着同步它:

public class MySensorListener implements SensorEventListener{

    // ...

    public synchronized void onSensorChanged(SensorEvent event) {
        // ...
    }

}

这没用,所以我尝试了几种方法:

- 同步'this'对象

public class MySensorListener implements SensorEventListener{

    // ...

    public void onSensorChanged(SensorEvent event) {
        synchronized(this){
            // ...
        }
    }

}

- 同步isStarted变量:

public class MySensorListener implements SensorEventListener{

    Boolean mIsStarted = false;

    // ...

    public void onSensorChanged(SensorEvent event) {
        synchronized(mIsStarted){
            // ...
        }
    }

}

- 使用AtomicBoolean:

public class MySensorListener implements SensorEventListener{

    public AtomicBoolean mIsStarted = new AtomicBoolean(false);

    // ...

    public void onSensorChanged(SensorEvent event) {
        if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
            float z = event.values[2];

            if (z < -8f) {
                if (mIsStarted.compareAndSet(false, true)) {
                    // start child activity
                }

            } else if (z > -7f) {
                if (mIsStarted.compareAndSet(true, false)) {
                    // stop child activity
                }
            }
        }
    }

}

这些方法都不起作用,所以我想知道为什么会发生这种情况以及如何改变它并让它发挥作用?

提前谢谢!

1 个答案:

答案 0 :(得分:0)

在您的Android清单文件集中归属于活动android:launchMode="singleTask"

<activity
            android:name=".CategoryActivity"
            android:launchMode="singleTask"
            android:screenOrientation="portrait" >
        </activity>

我不太确定这会解决您的问题,但实际上当传感器再次启动您的活动时,因为它在signleTask中它将不会重新启动并且活动当前状态仍然存在。