Android 在后台长期服务且不会被杀死的活动
在Android上,我有一个名为Android 在后台长期服务且不会被杀死的活动,android,android-service,android-lifecycle,android-service-binding,Android,Android Service,Android Lifecycle,Android Service Binding,在Android上,我有一个名为FirstActivity的Activity,它启动一个名为MyService的服务,在后台进行网络工作活动和服务始终通过调用方法相互通信。 现在,当用户从FirstActivity导航到SecondActivity时,后台服务不应被终止或重新创建,而应保持活动状态并传递到SecondActivity,该服务现在将与服务通信 换句话说,服务应在两个活动s中的一个正在运行时运行,并且当用户在两个活动s之间导航时,服务不应停止。 其中一个活动s将始终位于前台,在此期间
FirstActivity
的Activity
,它启动一个名为MyService
的服务,在后台进行网络工作活动
和服务始终通过调用方法相互通信。
现在,当用户从FirstActivity
导航到SecondActivity
时,后台服务不应被终止或重新创建,而应保持活动状态并传递到SecondActivity
,该服务现在将与服务通信
换句话说,服务
应在两个活动
s中的一个正在运行时运行,并且当用户在两个活动
s之间导航时,服务不应停止。
其中一个活动
s将始终位于前台,在此期间,该服务(最好)不会被终止。我认为这不应该是一个问题,因为这两个活动中的一个始终处于活动状态,因此Android知道该服务很重要,而不是必须终止的东西
(如果没有办法阻止Android不时终止和重新创建服务,我需要一种方法来优雅地恢复服务的完整状态。)
总之,服务
的寿命应与两个活动
的“组合”寿命相同。它应该从第一个开始,在两个都被销毁之前停止。
那么下面的代码对于该设置和目标是否正确
public class MyService extends Service {
public class LocalBinder extends Binder {
public MyService getService() {
return MyService.this;
}
}
...
}
public class FirstActivity extends Activity {
private MyService mMyService;
private ServiceConnection mMainServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName className, IBinder service) {
MyService mainService = ((LocalBinder) service).getService();
mMyService = mainService;
mMyService.setCallback(FirstActivity.this);
}
@Override
public void onServiceDisconnected(ComponentName className) {
mMyService = null;
}
};
@Override
public void onCreate(Bundle savedInstanceState) {
...
startService(new Intent(FirstActivity.this, MyService.class));
}
@Override
protected void onResume() {
super.onResume();
bindService(new Intent(FirstActivity.this, MyService.class), mMainServiceConnection, Context.BIND_AUTO_CREATE);
}
@Override
protected void onPause() {
super.onPause();
if (mMainServiceConnection != null) {
unbindService(mMainServiceConnection);
}
if (mMyService != null) {
mMyService.setCallback(null);
}
if (!isUserMovingToSecondActivity) {
stopService(new Intent(FirstActivity.this, MyService.class));
}
}
@Override
public void onBackPressed() {
stopService(new Intent(FirstActivity.this, MyService.class));
super.onBackPressed();
}
...
}
public class SecondActivity extends Activity {
private MyService mMyService;
private ServiceConnection mMainServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName className, IBinder service) {
MyService mainService = ((LocalBinder) service).getService();
mMyService = mainService;
mMyService.setCallback(SecondActivity.this);
}
@Override
public void onServiceDisconnected(ComponentName className) {
mMyService = null;
}
};
@Override
protected void onResume() {
super.onResume();
bindService(new Intent(SecondActivity.this, MyService.class), mMainServiceConnection, Context.BIND_AUTO_CREATE);
}
@Override
protected void onPause() {
super.onPause();
if (mMainServiceConnection != null) {
unbindService(mMainServiceConnection);
}
}
@Override
protected void onDestroy() {
...
stopService(new Intent(SecondActivity.this, MyService.class));
}
...
}
这是在活动
s的后台保证长期服务不会被终止或重新创建的最佳方法吗
那么Context.BIND\u AUTO\u CREATE
呢?在这里设置此标志是否正确?关于Context.BIND\u ADJUST\u与\u ACTIVITY
和Context.BIND\u放弃\u优先级
——我需要这些吗?(非常感谢@corsair992提供了有用的指针!)
如果活动总是按该顺序调用(即FirstActivity
开始SecondActivity
,而不是相反的顺序,那么基本上,您应该尝试将服务的生命周期与FirstActivity
的生命周期“绑定”
一般而言(见下文的注意事项),这意味着:
- 在
FirstActivity.onCreate()
中调用startService()
- 在
FirstActivity.ondestory()
中调用stopService()
- 在两个活动的
onStart()
/onStop()
方法中调用bindService()
/unbindService()
(以访问Binder对象,并能够对其调用方法)
以这种方式启动的服务将一直处于活动状态,直到调用stopService()
,并且每个客户端都解除绑定,请参阅:
这两条路径并不是完全分开的。也就是说,您可以绑定到
已使用startService()启动的服务。在这种情况下,stopService()或
stopSelf()在所有客户机停止服务之前不会停止服务
解开束缚
以及:
当最后一个客户端与服务解除绑定时,系统将销毁
服务(除非服务也是由startService()启动的)
使用此基本策略,只要FirstActivity
存在,服务就会一直存在(即未销毁)。但是,重要的一点仍然存在:如果未明确处理配置更改(例如屏幕旋转),将导致活动重新启动,服务将被销毁(因为我们正在ondestory()
中调用stopService()
)
为了防止这种情况发生,您可以在实际停止服务之前进行检查(因为由于此原因而发生的ondestory()
回调意味着尽管活动的此特定实例正在被销毁,但随后将重新创建它)
因此,完整的解决方案如下:
public class FirstActivity extends Activity
{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
startService(new Intent(this, MyService.class));
}
private ServiceConnection mServiceConnection = new ServiceConnection() { ... }
@Override
protected void onStart() {
super.onStart();
bindService(new Intent(this, MyService.class), mServiceConnection, Context.BIND_AUTO_CREATE);
}
@Override
protected void onStop() {
unbindService(mServiceConnection);
super.onStop();
}
@Override
protected void onDestroy() {
if (!isChangingConfigurations())
stopService(new Intent(this, MyService.class));
super.onDestroy();
}
而SecondActivity
将仅实现onStart()
/onStop()
方法(以相同的方式)
关于您的特定实现,请注意以下几点:
- 无需重写
onBackPressed()
,因为如果活动被销毁,将调用必要的生命周期方法(另外,可以在不按后退按钮的情况下完成,例如,如果对其调用finish()
)
- 在
onDestroy()
中停止服务,而不是在onPause()
中停止服务,这样您就不必检查isUserMovingToSecondActivity
您是否尝试过该代码,或者在尝试之前是否询问过?如果您尝试过,是否出现任何错误?它是否表现得不符合您的预期?如果您真的尝试过,然后向我们寻求解决方案,我们将进行更有成效的讨论,并为社区和您自己提供更有用的答案,具体问题是您需要的have@DallaRosa是的,当然可以当然,我已经试过了。这是一个关于如何设计服务类和相应的活动
类的一般性问题,以使服务尽可能长且不被终止。用户报告称,此服务提供的功能在其中一个活动
类中不时停止可用。and I(a)发现当系统可能终止此服务时很难调试,以及(b)希望了解一些最佳实践或改进,这些实践或改进应适用于此服务,以实现明确的目标和要求。我可以看到您对服务的管理中存在许多问题。只有在第一个活动
被销毁时,您才需要停止它,或者依赖绑定并正确管理它。Ther有一些通用的