2012-11-20 38 views
1

如果智能手机颠倒,我试图从传感器事件侦听器启动子活动。最初的代码我写是这样的:Android 4:从传感器事件侦听器启动子活动:同步失败

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 
       } 
      } 
     } 
    } 

} 

现在我有这个问题,那安卓4.0设备启动的三倍左右,而不是一次活动。我认为这是因为onSensorChanged方法在很短的时间内被过度调用。 所以我试图进行同步:

public class MySensorListener implements SensorEventListener{ 

    // ... 

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

} 

这并没有工作,所以我试了多种方法:

-Synchronizing的 '这个' 对象

public class MySensorListener implements SensorEventListener{ 

    // ... 

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

} 

-Synchronizing的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 
       } 
      } 
     } 
    } 

} 

没有一种方法奏效,所以我想知道为什么会发生这种情况,我怎么能改变它并使其工作?

预先感谢您!

+0

我还尝试更改此行中侦听器的速率: manager.registerListener(this,manager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),SensorManager.SENSOR_DELAY_NORMAL); 至 manager.registerListener(this,manager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),1000000); ,因为它说我还可以输入“所需的延迟时间之间的微秒”,所以这应该是一秒钟的速率,所以足够的时间让锁工作,但这并没有改变任何东西... – user1448982

+0

当使isStarted变量静态和使用同步(这),我得到更好的结果,但错误仍然不时发生... – user1448982

回答

0

在您的Android清单文件集attribue到活动android:launchMode="singleTask"

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

我不是非常确信这将解决你的问题,但实际上,当传感器重新启动您的活动,因为它是在signleTask它不会重新启动和活动当前状态依然存在。

+0

我曾尝试过,但与此解决方案,它甚至不启动一次活动。 ..我想我必须停止所有其他活动才能启动它(所以我的方向侦听器的活动也会停止) – user1448982

+0

我认为您必须将此属性应用于您的目标活动,必须将其应用于目标活动? –

+0

嗯,你是对的,我在那里犯了一个错误,我把它应用到了错误的活动中,但是对于之前发生的事情,当我将它应用到正确的活动时,没有什么区别... – user1448982