caw*_*caw 12 android android-service android-lifecycle android-service-binding
在Android上,我有一个Activity
被叫FirstActivity
,它启动一个Service
名为MyService
在后台做网络的东西.该Activity
和Service
相互所有的时间通过调用方法通信.
现在,当用户从导航FirstActivity
到SecondActivity
,后台服务应该不会被杀死或重新创建的,但维持生命,并传递给SecondActivity
现在将是一个与服务进行通信.
换句话说,Service
只要两个Activity
s中的一个正在运行,它就应该运行,并且当用户在两个Activity
s 之间导航时它不应该停止.
其中一个Activity
将永远在前台,在此期间,服务应该(最佳)永远不会被杀死.我认为这应该不是问题,因为这两个中Activity
的一个总是活跃的,因此Android知道服务很重要而不是必须被杀死的东西.
(如果没有办法阻止Android不时地杀死和重新创建服务,我需要一种方法来优雅地恢复服务的完整状态.)
总而言之,它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));
}
...
}
Run Code Online (Sandbox Code Playgroud)
这是保证在Activity
不会被杀死或重新创建的s 背景下提供持久服务的最佳方式吗?
怎么样Context.BIND_AUTO_CREATE
?将此标志设置在此处是否正确?怎么样Context.BIND_ADJUST_WITH_ACTIVITY
和Context.BIND_WAIVE_PRIORITY
-我需要这些?
(非常感谢@ corsair992提供了有用的指示!)
如果活动总是按照这个顺序调用(即FirstActivity
开始SecondActivity
,而不是相反,那么你应该基本上试图将服务的生命周期"绑定"到FirstActivity
生命周期.
一般情况下(见后面的警告),这意味着:
startService()
在FirstActivity.onCreate()
.stopService()
在FirstActivity.onDestroy()
.bindService()
/ unbindService()
在两个活动的onStart()
/ onStop()
方法中(以访问Binder对象,并能够调用它上面的方法).以这种方式启动的服务将一直处于活动状态,直到stopService()
被调用并且每个客户端解除绑定,请参阅管理服务的生命周期:
这两条路径并不完全分开.也就是说,您可以绑定到已使用startService()启动的服务.(...)在这种情况下,stopService()或stopSelf()实际上不会停止服务,直到所有客户端解除绑定.
和:
当最后一个客户端从服务解除绑定时,系统会销毁该服务(除非该服务也是由startService()启动的).
有了这个基本策略,服务将FirstActivity
在周围生存(即不会被破坏).然而,一个重要的观点仍然是:在配置发生变化时(如屏幕旋转)未明确处理会造成活性重启本身,该服务将被销毁(因为我们调用stopService()
的onDestroy()
).
为了防止这种情况,您可以isChangingConfigurations()
在实际停止服务之前进行检查(因为onDestroy()
由于这个原因而发生的回调意味着虽然正在销毁Activity的这个特定实例,但之后将重新创建它.
因此,完整的解决方案将是这样的:
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();
}
Run Code Online (Sandbox Code Playgroud)
虽然SecondActivity
将只执行onStart()
/ onStop()
方法(以同样的方式).
关于您的特定实现的几点说明:
onBackPressed()
,因为如果活动被破坏,将调用必要的生命周期方法(此外,它可以在不按下后退按钮的情况下完成,例如,如果调用finish()
它).onDestroy()
而不是让onPause()
您不必检查isUserMovingToSecondActivity
. 归档时间: |
|
查看次数: |
689 次 |
最近记录: |