在Android上,我有一个名为Activity
的{{1}},它会启动名为FirstActivity
的{{1}}来在后台执行网络工作。 Service
和MyService
通过调用方法始终相互沟通。
现在,当用户从Activity
导航到Service
时,后台服务应该不被杀死或重新创建,但保持活跃并传递给{{1}现在将是与服务通信的人。
换句话说,只要两个FirstActivity
中的一个正在运行,SecondActivity
就会运行,当用户在两个{{1}之间导航时,它不应该停止}}第
其中一个SecondActivity
将始终位于前台,在此期间,服务应该(最佳)永远不会被杀死。我认为这应该不是问题,因为这两个Service
中的一个总是处于活动状态,因此Android知道服务很重要,而不是必须被杀死的东西。
(如果无法阻止Android不时杀死并重新创建服务,我需要一种方法来优雅地恢复服务的完整状态。)
总而言之,Activity
应该与两个Activity
“合并”的生命周期相同。它应该从它们中的第一个开始,并且在它们都被破坏之前停止。
以下代码对于该设置和目标是否正确?
Activity
这是保证Activity
背景下不会被杀死或重新创建的长效服务的最佳方式吗?
Service
怎么样?将此标志设置在此处是否正确?那么Activity
和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));
}
...
}
呢?我需要这些吗?
答案 0 :(得分:7)
(非常感谢@ corsair992提供了有用的指示!)
如果总是以该顺序调用活动(即FirstActivity
开始SecondActivity
,而从不相反,那么你基本上应该尝试"绑定"服务的生命周期到FirstActivity
的生命周期。
一般情况下(请参阅后面的警告),这意味着:
startService()
中致电FirstActivity.onCreate()
。stopService()
中致电FirstActivity.onDestroy()
。bindService()
/ unbindService()
方法中调用onStart()
/ onStop()
(以便访问Binder对象,并能够在其上调用方法) 以这种方式启动的服务将一直存在,直到stopService()
被称为且每个客户端解除绑定,请参阅Managing the Lifecycle of a Service:
这两条路径并非完全分开。也就是说,你可以绑定到 已经使用startService()启动的服务。 (...)在这种情况下,stopService()或 stopSelf()实际上并没有停止服务直到所有客户端 解除绑定。
和
当最后一个客户端从服务解除绑定时,系统会破坏该服务 service(除非服务也是由startService()启动的)。
有了这个基本策略,只要FirstActivity
到处(即它没有被销毁),服务就会存在。但是,重要的一点仍然存在:如果配置更改(例如屏幕旋转)未明确处理将导致活动自行重启,服务将被销毁(因为我们正在调用{{ 1}}在stopService()
)。
为了防止这种情况,您可以在实际停止服务之前检查isChangingConfigurations()
(因为由于这个原因发生onDestroy()
回调意味着尽管活动的这个特定实例正在被销毁,但它将是之后再创造。
因此,完整的解决方案将是:
onDestroy()
虽然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()
,因为如果活动被销毁,将调用必要的生命周期方法(此外,它可以在不按后退按钮的情况下完成,例如,如果调用{{ 1}}就可以了。)onBackPressed()
而不是finish()
停止服务可以使您免于检查onDestroy()
。