在后台不会被杀死的长期服务活动

时间:2014-12-17 05:19:04

标签: android android-service android-lifecycle android-service-binding

在Android上,我有一个名为Activity的{​​{1}},它会启动名为FirstActivity的{​​{1}}来在后台执行网络工作。 ServiceMyService通过调用方法始终相互沟通。

现在,当用户从Activity导航到Service时,后台服务应该被杀死或重新创建,但保持活跃并传递给{{1}现在将是与服务通信的人。

换句话说,只要两个FirstActivity中的一个正在运行,SecondActivity就会运行,当用户在两个{{1}之间导航时,它不应该停止}}第

其中一个SecondActivity将始终位于前台,在此期间,服务应该(最佳)永远不会被杀死。我认为这应该不是问题,因为这两个Service中的一个总是处于活动状态,因此Android知道服务很重要,而不是必须被杀死的东西。

(如果无法阻止Android不时杀死并重新创建服务,我需要一种方法来优雅地恢复服务的完整状态。)

总而言之,Activity应该与两个Activity“合并”的生命周期相同。它应该从它们中的第一个开始,并且在它们都被破坏之前停止。

以下代码对于该设置和目标是否正确?

Activity

这是保证Activity背景下不会被杀死或重新创建的长效服务的最佳方式吗?

Service怎么样?将此标志设置在此处是否正确?那么Activitypublic 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)); } ... } 呢?我需要这些吗?

1 个答案:

答案 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()