Java 即使在活动被销毁后,Android处理程序仍会运行一段时间

Java 即使在活动被销毁后,Android处理程序仍会运行一段时间,java,android,android-studio,sensors,Java,Android,Android Studio,Sensors,我了解到,handler.postDelayed方法有助于将任务暂停任意时间。因此,我将其写入光传感器,以便传感器仅每2秒检测一次光,以节省电池寿命: public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentV

我了解到,
handler.postDelayed
方法有助于将任务暂停任意时间。因此,我将其写入光传感器,以便传感器仅每2秒检测一次光,以节省电池寿命:

public class MainActivity extends Activity {


    @Override
    protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    SensorManager sm = (SensorManager) getSystemService(SENSOR_SERVICE);
    Sensor light = sm.getDefaultSensor(Sensor.TYPE_LIGHT);
    SensorEventListener listener;

    if (light != null) {

        final Handler handler = new Handler();
        final Runnable task = new Runnable() {
            @Override
            public void run() {
                sm.registerListener(listener, light, SensorManager.SENSOR_DELAY_NORMAL);
            }
        };

        listener = new SensorEventListener() {

            @Override
            public void onAccuracyChanged(Sensor sensor, int accuracy) {
                Toast.makeText(MainActivity.this, "accuracy changed!", Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onSensorChanged(SensorEvent event) {

                sm.unregisterListener(listener, light);

                // Do the stuff here with the received sensor light value, which is event.values[0]
                
                handler.postDelayed(task, 2000);
            }
        };

    }

    @Override
    protected void onPause() {
        super.onPause();
        sm.unregisterListener(listener, light);
    }

    @Override
    protected void onResume() {
        super.onResume();
        sm.registerListener(listener, light, SensorManager.SENSOR_DELAY_NORMAL);
    }

    @Override
    protected void onStop() {
        super.onStop();
        sm.unregisterListener(listener, light);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        sm.unregisterListener(listener, light);
    }
}

起初,它似乎运作良好。但我发现,每次我退出应用程序时,它都会持续检测到灯光20到30秒,好像活动仍在进行。我做错了什么?我甚至添加了onStop和onDestroy方法,只是为了确保它正确关闭。

在活动的onDestroy()中清除处理程序

handler.removeCallbacksAndMessages(null);

它会立刻停止

在我尝试的一秒钟内,我认为它奏效了:)。但我仍然不明白,问题出在哪里?处理程序不知道活动已被破坏,将以任何方式执行发布的任务,并且由于该任务重新注册侦听器,这将导致无休止的循环和内存泄漏,因为task和listener是匿名类,其中包含对活动的隐式引用。处理程序在单独的线程上工作。在应用程序被杀死时,垃圾收集器可能会也可能不会销毁它。此外,这还可以防止任何内存泄漏。@jaswart“处理程序在单独的线程上工作”,这是不准确的。如果在Handlar的构造中没有指定任何其他内容,它将在创建它的同一线程上运行,在本例中是主线程。