Android的Handler在活动被销毁后仍然持续运行一段时间。

huangapple 未分类评论44阅读模式
英文:

Android Handler keeps running for a while even after the activity has been destroyed

问题

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

  1. public class MainActivity extends Activity {
  2. @Override
  3. protected void onCreate(Bundle savedInstanceState) {
  4. super.onCreate(savedInstanceState);
  5. setContentView(R.layout.activity_main);
  6. SensorManager sm = (SensorManager) getSystemService(SENSOR_SERVICE);
  7. Sensor light = sm.getDefaultSensor(Sensor.TYPE_LIGHT);
  8. SensorEventListener listener;
  9. if (light != null) {
  10. final Handler handler = new Handler();
  11. final Runnable task = new Runnable() {
  12. @Override
  13. public void run() {
  14. sm.registerListener(listener, light, SensorManager.SENSOR_DELAY_NORMAL);
  15. }
  16. };
  17. listener = new SensorEventListener() {
  18. @Override
  19. public void onAccuracyChanged(Sensor sensor, int accuracy) {
  20. Toast.makeText(MainActivity.this, "accuracy changed!", Toast.LENGTH_SHORT).show();
  21. }
  22. @Override
  23. public void onSensorChanged(SensorEvent event) {
  24. sm.unregisterListener(listener, light);
  25. // 在此处处理接收到的传感器光线值,即event.values[0]
  26. handler.postDelayed(task, 2000);
  27. }
  28. };
  29. }
  30. }
  31. @Override
  32. protected void onPause() {
  33. super.onPause();
  34. sm.unregisterListener(listener, light);
  35. }
  36. @Override
  37. protected void onResume() {
  38. super.onResume();
  39. sm.registerListener(listener, light, SensorManager.SENSOR_DELAY_NORMAL);
  40. }
  41. @Override
  42. protected void onStop() {
  43. super.onStop();
  44. sm.unregisterListener(listener, light);
  45. }
  46. @Override
  47. protected void onDestroy() {
  48. super.onDestroy();
  49. sm.unregisterListener(listener, light);
  50. }
  51. }

起初,它似乎正常工作。但我发现每次退出应用程序时,它会持续大约20到30秒钟检测光线,就好像活动仍然打开一样。我做错了什么?我甚至添加了onStoponDestroy方法,只是为了确保它正确关闭。

英文:

I read that the handler.postDelayed method helps pause a task for any amount of time. So I wrote it into the light sensor so that the sensor only detects light every 2 seconds, in order to save battery life:

  1. public class MainActivity extends Activity {
  2. @Override
  3. protected void onCreate(Bundle savedInstanceState) {
  4. super.onCreate(savedInstanceState);
  5. setContentView(R.layout.activity_main);
  6. SensorManager sm = (SensorManager) getSystemService(SENSOR_SERVICE);
  7. Sensor light = sm.getDefaultSensor(Sensor.TYPE_LIGHT);
  8. SensorEventListener listener;
  9. if (light != null) {
  10. final Handler handler = new Handler();
  11. final Runnable task = new Runnable() {
  12. @Override
  13. public void run() {
  14. sm.registerListener(listener, light, SensorManager.SENSOR_DELAY_NORMAL);
  15. }
  16. };
  17. listener = new SensorEventListener() {
  18. @Override
  19. public void onAccuracyChanged(Sensor sensor, int accuracy) {
  20. Toast.makeText(MainActivity.this, "accuracy changed!", Toast.LENGTH_SHORT).show();
  21. }
  22. @Override
  23. public void onSensorChanged(SensorEvent event) {
  24. sm.unregisterListener(listener, light);
  25. // Do the stuff here with the received sensor light value, which is event.values[0]
  26. handler.postDelayed(task, 2000);
  27. }
  28. };
  29. }
  30. @Override
  31. protected void onPause() {
  32. super.onPause();
  33. sm.unregisterListener(listener, light);
  34. }
  35. @Override
  36. protected void onResume() {
  37. super.onResume();
  38. sm.registerListener(listener, light, SensorManager.SENSOR_DELAY_NORMAL);
  39. }
  40. @Override
  41. protected void onStop() {
  42. super.onStop();
  43. sm.unregisterListener(listener, light);
  44. }
  45. @Override
  46. protected void onDestroy() {
  47. super.onDestroy();
  48. sm.unregisterListener(listener, light);
  49. }
  50. }

At first it seemed to work fine. But I found that every time I exit the app it kept detecting the light for like 20 to 30 seconds as if the activity was still open. What am I doing wrong? I even added both the onStop and onDestroy methods just to be sure it was closing correctly.

答案1

得分: 2

在您的活动的 onDestroy() 中,清除您的处理程序,如下所示:

  1. handler.removeCallbacksAndMessages(null);

这样就会立即停止!

英文:

Inside the onDestroy() of your activity clear your handler like

  1. handler.removeCallbacksAndMessages(null);

And it will stop right away!

huangapple
  • 本文由 发表于 2020年7月26日 00:30:16
  • 转载请务必保留本文链接:https://java.coder-hub.com/63090772.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定