Android后台服务状态信息

发布于 2024-10-08 04:56:46 字数 1926 浏览 0 评论 0原文

我有一个活动可以通过控制后台服务的启动和停止。单击按钮。当服务未运行时,按钮显示“启动服务”;当服务正在运行时,按钮显示“停止服务”。单击按钮时应该发生的逻辑以相同的方式切换(如果服务未运行,我们启动它并在单击按钮时绑定到它,如果服务正在运行,我们停止它并取消绑定)。

请查看下面的代码摘录以获取更多信息。

绑定和取消绑定

虽然该服务目前只能通过“停止服务”按钮停止,但我在 onPause 中取消绑定服务并在 onResume 中重新绑定它。这有道理吗? onPause 和 onResume 生命周期方法被频繁调用,因此这是大量的绑定和解除绑定开销,但由于 onPause 总是在应用程序被杀死之前调用,我认为这是释放服务绑定和避免泄漏的最佳位置。

后退按钮

我也不确定按下“后退”按钮后要做什么。当按下“后退”按钮时,服务是否应该在后台保持运行(与 Android 音乐应用程序中的行为相同)?如果是,那么保存服务正在运行的信息的正确方法是什么(因为按下“后退”按钮时不会调用 onSaveInstanceState 我想知道保存应用程序状态的最干净的方法是什么- 在我的例子中是 isServiceRunning 布尔变量)?当活动再次启动时,我需要此信息来在开始/停止按钮上设置正确的文本(相对于后台服务的状态)。一种可能的替代方案是允许活动正常完成而不保存任何服务状态信息 (isServiceRunning)。我可以从 ActivityManager 的 onCreate 中获取此信息,我可以在其中查询正在运行的服务。

另一方面,如果应在按“后退”按钮时停止服务,我应该在哪里实现服务停止? onDestroy 将是这个问题的自然答案,但我遇到了问题,因为 onDestroy 也在活动重新启动时被调用(例如,方向改变时),并且我不想在这种情况下停止服务。

    public class ServiceController extends Activity {
 public void onStartClick(View v) {
  if (!isServiceRunning) {
   button.setText("STOP");
   isServiceRunning = true;
   startService(...)
   bindService(...)
  } else {
   button.setText("START");
   isServiceRunning = false;
   unbindService(...)
   stopService(...)
  }
 }

 @Override
 protected void onResume() {
  super.onResume();
  if (isServiceRunning) {
   button.setText("STOP");
   bindService(...);
  }
 }

 @Override
 protected void onPause() {
  super.onPause();
  if (mBoundAccService != null) {
   unbindService(...);
  }
 }

 @Override
 protected void onRestoreInstanceState(Bundle savedInstanceState) {
  super.onRestoreInstanceState(savedInstanceState);
  if (savedInstanceState != null) {   
   isServiceRunning = savedInstanceState.getBoolean(ID_SERVICE_RUNNING);
  }
 }

 @Override
 protected void onSaveInstanceState(Bundle outState) {
  super.onSaveInstanceState(outState);
  outState.putBoolean(ID_SERVICE_RUNNING, isServiceRunning);
 }
    } 

I have an activity that controls starting and stopping of a background service via. a button click. When the service is not running the button says 'START SERVICE' and when the service is running the button says 'STOP SERVICE'. The logic, what should happen on button click, toggles in the same manner (if the service is not running we start it and bind to it on button click and we stop it and unbind from it if the service is running).

Please, take a look at the code excerpt bellow for more information.

Bind and unbind

While the service can currently only be stopped through the STOP SERVICE button, I'm unbinding the service in onPause and rebinding it in onResume. Does this make sense? onPause and onResume lifecycle methods are called quite often, so this is a lot of binding and unbinding overhead, but as onPause is always called before the application could be killed, I think this is the best place for releasing service bindings and to avoid leaks.

BACK button

I'm also not sure what to do when the BACK button is pressed. Should the service remain running in the background when the BACK button is pressed (the same behaviour as in Android Music application)? If yes, what would be the proper way to persist the information that the service is running (as onSaveInstanceState is not getting called on BACK button pressed I am wondering what would be the cleanest way to persist the application's state - in my case the isServiceRunning boolean variable)? I need this information to set the correct text on the start/stop button (with respect to the state of the background service) when the activity will be started again. One possible alternative would also be to allow the activity to finish normally without saving any service state information (isServiceRunning). I could get this information in onCreate from ActivityManager, where I could query for the running services.

On the other hand, if the service should be stopped on the BACK button press, where should I implement stopping of the service? onDestroy would be a natural answer to this question, but I'm facing problems as onDestroy is also getting called on activity restart (e.g. on orientation change) and I do not want to stop the service in that case.

    public class ServiceController extends Activity {
 public void onStartClick(View v) {
  if (!isServiceRunning) {
   button.setText("STOP");
   isServiceRunning = true;
   startService(...)
   bindService(...)
  } else {
   button.setText("START");
   isServiceRunning = false;
   unbindService(...)
   stopService(...)
  }
 }

 @Override
 protected void onResume() {
  super.onResume();
  if (isServiceRunning) {
   button.setText("STOP");
   bindService(...);
  }
 }

 @Override
 protected void onPause() {
  super.onPause();
  if (mBoundAccService != null) {
   unbindService(...);
  }
 }

 @Override
 protected void onRestoreInstanceState(Bundle savedInstanceState) {
  super.onRestoreInstanceState(savedInstanceState);
  if (savedInstanceState != null) {   
   isServiceRunning = savedInstanceState.getBoolean(ID_SERVICE_RUNNING);
  }
 }

 @Override
 protected void onSaveInstanceState(Bundle outState) {
  super.onSaveInstanceState(outState);
  outState.putBoolean(ID_SERVICE_RUNNING, isServiceRunning);
 }
    } 

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

看春风乍起 2024-10-15 04:56:46

首先..我不理解解除绑定onPause()的概念。如果您这样做,服务将随着您的活动而启动和停止(这也意味着该服务本质上是一个活动)。

这就是我的应用程序所做的。

当用户选择从(显然)活动开始时,服务已使用以下代码启动。

startService(new Intent(this, MyService.class));

当用户选择“停止”(同一按钮或另一个按钮)时

stopService(new Intent(this, MUMService.class));

在Service类上,我实现了onStart和onDestroy方法来控制服务进程。

我没有覆盖后退按钮(Android 不鼓励这样做),但如果您需要......这里是代码(在您的活动中)

@覆盖

public boolean onKeyDown(int keyCode, KeyEvent event) {

if (keyCode == KeyEvent.KEYCODE_BACK) {

Firstly.. I did not understand the concept of unbinding onPause(). If you do this, the service will start and stop with your activity (Which also means the service is essentially an activity).

This is what my application did.

When user selected Start from (obviously) activity, the service has started with the following code.

startService(new Intent(this, MyService.class));

And when the user selects Stop (either same button or another button)

stopService(new Intent(this, MUMService.class));

On the Service class, I have implemented onStart and onDestroy methods to control the service process.

I did not override the back button (This is discouraged by Android ) but if you need be.. here is the code (in your activity)

@Override

public boolean onKeyDown(int keyCode, KeyEvent event) {

if (keyCode == KeyEvent.KEYCODE_BACK) {

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文