java - Android - 确定 Compass 中的内存泄漏 (SensorManager)

标签 java android memory-leaks sensors

我使用单例模式实现了一个简单的指南针类。一旦我向传感器管理器注册了加速度计和磁力计监听器,内存消耗就会增加。我的 GPS 类与指南针类非常相似,并且我没有出现内存泄漏问题。我在 onSensorChanged 方法中放置了一个断点,分配的内存每 5 次调用就会增加 0.01 MB 。我将在下面添加相应的代码。也许有人知道出了什么问题。也许没有问题,内存略有增加,这很正常?

主要 Activity

public class MainActivity extends ActionBarActivity {
    [...]
    protected void onCreate( Bundle savedInstanceState ) {
        super.onCreate( savedInstanceState );
        setContentView( R.layout.activity_main );

        this.mGPS = GPSTracker.getInstance();
        this.mGPS.start( MainActivity.this );
        this.mLocation = this.mGPS.getLatLng();

        this.mCompass = CompassTracker.getInstance();
        // uncomment the following line will stop the memory leak
        this.mCompass.start( MainActivity.this );
    }
    [...]
}

指南针类

public class CompassTracker implements SensorEventListener {
    [...]
    /**
     * The minimum time between updates in milliseconds.
     */
    private static final int MIN_TIME_BW_UPDATES = 500; //  1 * 60 * 1000 -> 1 Minute

    private void start( Context context ) {
        this.mSensorManager = (SensorManager) context.getSystemService( Context.SENSOR_SERVICE );

        this.mAccelerometer = this.mSensorManager.getDefaultSensor( Sensor.TYPE_ACCELEROMETER );
        this.mMagnetometer = this.mSensorManager.getDefaultSensor( Sensor.TYPE_MAGNETIC_FIELD );

        boolean enAcc = this.mSensorManager.registerListener( this, this.mAccelerometer, MIN_TIME_BW_UPDATES );
        boolean enMag = this.mSensorManager.registerListener( this, this.mMagnetometer, MIN_TIME_BW_UPDATES );

        if ( enAcc && enMag ) {
            this.mStatus = States.ENABLED;
        } else {
            this.mStatus = States.NOT_AVAILABLE;
            this.stop();
        }
    }

    @Override
    public void onSensorChanged( SensorEvent event ) {
        final float alpha = 0.97f;

        if ( event.sensor.getType() == Sensor.TYPE_ACCELEROMETER ) {
            this.mGravity[0] = alpha * this.mGravity[0] + ( 1 - alpha ) * event.values[0];
            this.mGravity[1] = alpha * this.mGravity[1] + ( 1 - alpha ) * event.values[1];
            this.mGravity[2] = alpha * this.mGravity[2] + ( 1 - alpha ) * event.values[2];
        }

        if ( event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD ) {
            this.mGeomagnetic[0] = alpha * this.mGeomagnetic[0] + ( 1 - alpha ) * event.values[0];
            this.mGeomagnetic[1] = alpha * this.mGeomagnetic[1] + ( 1 - alpha ) * event.values[1];
            this.mGeomagnetic[2] = alpha * this.mGeomagnetic[2] + ( 1 - alpha ) * event.values[2];
        }

        float R[] = new float[9];
        float I[] = new float[9];

        if ( SensorManager.getRotationMatrix( R, I, mGravity, mGeomagnetic ) ) {
            this.mOrientation = SensorManager.getOrientation( R, this.mOrientation );
        }

        // inform the listener
        if( this.orientationChangedListener != null )
            this.orientationChangedListener.onOrientationChanged( this.mOrientation );
    }


    /**
     * Orientation listener
     * @param orientationChangedListener
     */
    public void setOrientationChangedListener( OrientationChangedListener orientationChangedListener ) {
        this.orientationChangedListener = orientationChangedListener;
    }
    [...]
}

提前致谢!

最佳答案

每次

this.mSensorManager = (SensorManager) context.getSystemService( Context.SENSOR_SERVICE );

被调用时,当前 MainActivity 的实例将与您的单例类绑定(bind)。也许您的 GPS 类别会导致相同的内存泄漏,但速度没有这个那么快。

你在这里所做的是糟糕的设计。特别是在 Activity 中使用单例类。像这样重构你的代码:

  1. 了解 Android 文档中的服务
  2. 将传感器内容放入服务中。
  3. 在服务的 onCreate 方法中,使用其上下文获取 GPS 和指南针的系统服务
  4. 在服务的 onDestroy 方法中取消绑定(bind)系统服务
  5. 使用 LocalBroadcastManager 等广播将数据传递到其他组件,例如您的 Activity

关于java - Android - 确定 Compass 中的内存泄漏 (SensorManager),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28798585/

相关文章:

java - 无法在 Maven2 中导入 Commons DbUtils

android - 发送短信时查看确认充值账单对话框

android - 支持设计库异常

iphone - 检查仪器中的内存分配

javascript - JS 垃圾回收 : Reference to object properties cause whole object to remain on Memory?

iphone - NSArray 内存泄漏!无法获取为什么?

java - 使用 SystemLookAndFeel 单击时透明 JButton

java - 通过 Thunderbird\Outlook 连接到本地主机 POP3 服务器

java - 无法启动代理

java - Android IndexOutOfBoundException