有没有办法让getSystemService()每次都在Android中返回一个全新的实例?

时间:2016-02-09 00:23:45

标签: android android-sensors sensormanager

在Android Wear中,使用SensorManager重复注册和取消注册SensorEventListener会导致SensorManager失败。我想知道是否有一种方法可以在每次加载片段时获得SensorManager的新实例。因此,我可以获取一个新的SensorManager,注册我的侦听器,并在片段被销毁时取消注册它们,然后在下次加载片段时取消引用该SensorManager并获取一个新的。

在我的片段中,我目前正在这样做:

@Override
public View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
    // ... 
    mSensorMgr = (SensorManager) mMainWearActivity.getSystemService(Activity.SENSOR_SERVICE);
    // ...
}

private void startListening(){

    yGesture.setOnShakeListener(yListener);
    xGesture.setOnShakeListener(xListener);
    mSensorMgr.registerListener(yGesture, mSensorMgr.getDefaultSensor(Sensor.TYPE_GYROSCOPE), SensorManager.SENSOR_DELAY_NORMAL);
    mSensorMgr.registerListener(xGesture, mSensorMgr.getDefaultSensor(Sensor.TYPE_GYROSCOPE), SensorManager.SENSOR_DELAY_NORMAL);
}

@Override
public void onResume(){
    super.onResume();
    startListening();
}

@Override
public void onPause(){
    stopListening();
    super.onPause();
}

private void stopListening(){

    mSensorMgr.unregisterListener(yGesture);
    mSensorMgr.unregisterListener(xGesture);
    mSensorMgr = null;
}

我需要mSensorMgr = (SensorManager) mMainWearActivity.getSystemService(Activity.SENSOR_SERVICE);来返回一个新实例,否则多次注册和取消注册侦听器会导致SensorManager失败。这可能吗?最好不必制作新的活动,只是坚持使用片段。感谢

编辑:

我已经将使用sensorManager的监听器注册到onResume(),但同样的问题仍然存在。这是Android Wear框架中的错误吗?

2 个答案:

答案 0 :(得分:1)

一般来说,您总是希望使用正确配对的Activity或Fragment生命周期方法来注册和取消注册任何类型的侦听器。所以你会使用create / destroy,或者开始/停止,或者恢复/暂停。

在您的特定情况下,您正在onCreateView中注册,对于片段实例只注册 一次,但是,在onPause期间会发生取消注册,可以多次调用。一旦这个片段由于任何原因暂停(并且有很多原因可能发生),你的听众将永远消失,直到创建片段的新实例。

因此,您可能需要考虑使用create / destroy或start / stop,具体取决于您尝试对片段中的侦听器执行的操作。如果您不了解这些生命周期方法,请研究here

答案 1 :(得分:0)

  

我是否有办法获得SensorManager的新实例......?

没有。 getSystemService(Context.SENSOR_SERVICE)返回的对象基本上是系统级服务的接口对象。该设备上只有一个该服务实例。

通过使用所选标​​记" SensorManager"创建Android Studio SensorManager过滤器,您可以了解logcat服务正在执行的操作。和调试级别。过滤器将启用如下输出:

D/SensorManager: registerListener :: 6, CM3323 RGB Sensor, 200000, 0,
D/SensorManager: unregisterListener ::

查看此输出可能会帮助您在注册和取消注册监听器的方式中看到意外情况。

onCreateView()注册您的听众并在onPause()取消注册是不太好的做法。当片段的活动暂停并恢复时,片段也会暂停并恢复,不会调用onCreateView()。这在documentation

中有解释

您也可以尝试尝试较慢的传感器更新速率。 SENSOR_DELAY_GAME是20毫秒,可能比您的应用程序所需的速度快。 SENSOR_DELAY_UI是67毫秒,SENSOR_DELAY_NORMAL是200毫秒。