簡體   English   中英

Android-確定指南針中的內存泄漏(SensorManager)

[英]Android - Determine Memory Leak in Compass (SensorManager)

我使用單例模式實現了一個簡單的指南針類。 一旦我向傳感器管理器注冊了加速度計和磁力計監聽器,內存消耗就會增加。 我的GPS類與指南針類非常相似,並且我對內存泄漏沒有任何問題。我在onSensorChanged方法中放置了一個斷點,並且每5次調用分配的內存增加了0.01 MB。 我將在下面添加相應的代碼。 也許有人知道出了什么問題。 也許內存有一點增加是正常的,這沒有問題,這是正常的嗎?

主要活動

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的實例將與您的singleton類聯系在一起。 您的GPS類可能會導致相同的內存泄漏,但速度不及此速度。

您在這里所做的是糟糕的設計。 特別是在Activity中使用單例類。 像這樣重構代碼:

  1. 在Android文檔中了解Service
  2. 將傳感器塞入服務中。
  3. 在服務的onCreate方法中,使用其上下文獲取GPS和指南針的系統服務
  4. 用服務的onDestroy方法解除系統服務的綁定
  5. LocalBroadcastManager一樣使用Broadcasting將數據傳遞到其他組件,例如您的Activity

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM