我有一个控制后台服务启动和停止的活动。按一下按钮。当服务未运行时,按钮显示“START SERVICE”,当服务运行时,按钮显示“STOP SERVICE”。逻辑,按钮点击应该发生什么,以相同的方式切换(如果服务没有运行,我们启动它并在按钮点击时绑定它,我们停止它并在服务运行时解除绑定)。
请参阅下面的代码摘录以获取更多信息。
绑定和取消绑定
虽然目前只能通过STOP SERVICE按钮停止服务,但我在onPause中取消绑定服务并在onResume中重新绑定它。这有意义吗? onPause和onResume生命周期方法经常被调用,所以这是很多绑定和解除绑定的开销,但是因为onPause总是在应用程序被杀死之前被调用,我认为这是释放服务绑定和避免泄漏的最佳位置。
返回按钮
我也不确定按下BACK按钮时该怎么做。当按下BACK按钮时,服务是否仍然在后台运行(与Android Music应用程序中的行为相同)?如果是,那么保持服务运行信息的正确方法是什么(因为 onSaveInstanceState 没有按下BACK按钮被调用)我想知道什么是最简洁的方法来保持应用程序的状态 - 在我的例子中是isServiceRunning布尔变量)?我需要此信息,以便在再次启动活动时在开始/停止按钮(相对于后台服务的状态)上设置正确的文本。一种可能的替代方案还是允许活动正常完成而不保存任何服务状态信息(isServiceRunning)。我可以从ActivityManager中获取onCreate中的这些信息,在那里我可以查询正在运行的服务。
另一方面,如果应该按BACK按钮停止服务,我应该在哪里停止服务? 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);
}
}
答案 0 :(得分:0)
首先..我不理解取消绑定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){