当我注意到两个相互矛盾的观点时,我正在浏览android中的服务文档:
在服务文档中,它在Managing the Lifecycle of a Service
中指定这两条路径并非完全分开。也就是说,你可以绑定到 已经使用startService()启动的服务。例如,a 可以通过调用startService()启动背景音乐服务 有一个识别要播放的音乐的意图。可能在以后 用户想要对玩家进行一些控制或获得 关于当前歌曲的信息,一个活动可以绑定到 通过调用bindService()来进行服务。在这种情况下,stopService()或 stopSelf()实际上并没有停止服务直到所有客户端 解除绑定。
但是在Managing the Lifecycle of a Bound Service
中关于绑定服务的文档中但是,如果您选择实现onStartCommand()回调 方法,那么你必须明确停止服务,因为服务 现在被认为是开始了。在这种情况下,服务运行直到 该服务使用stopSelf()或其他组件调用自行停止 stopService(),无论它是否绑定到任何客户端。
可能是我,但我认为这些陈述是矛盾的。任何人都可以澄清......
答案 0 :(得分:75)
同意文件更清晰。他们想说的是:
创建了一个非常简单的Activity和Service,并运行了以下start / stop / bind / unbind序列。我观察到这些调用给出了以下结果。
结合 - 解绑定
bindService() caused:
onCreate()
onBind()
unbindService() caused:
onUnbind()
onDestroy()
启动结合 - 解绑定停止
startService() caused:
onCreate()
onStartCommand()
bindService() caused:
onBind()
unbindService() caused:
onUnbind()
stopService() caused:
onDestroy()
开始绑定-止解除绑定
startService() caused:
onCreate()
onStartCommand()
bindService() caused:
onBind()
stopService() caused:
-- nothing
unbindService() caused:
onUnbind()
onDestroy()
绑定 - 开始 - 停止 - 取消绑定
bindService() caused:
onCreate()
onBind()
startService() caused:
onStartCommand()
stopService() caused:
-- nothing -- still running
unbindService() caused:
onUnbind()
onDestroy()
绑定 - 开始 - 解除绑定停止
bindService() caused:
onCreate()
onBind()
startService() caused:
onStartCommand()
unbindService() caused:
onUnbind()
stopService() caused:
onDestroy()
正如您所看到的,在调用bind和start的每种情况下,服务都会一直运行,直到调用unbind和stop。解绑/停止的顺序并不重要。
以下是我的简单测试应用程序中单独按钮调用的示例代码:
public void onBindBtnClick(View view) {
Intent intent = new Intent(MainActivity.this, ExampleService.class);
bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
}
public void onUnbindBtnClick(View view) {
if (serviceIsBound) {
unbindService(serviceConnection);
serviceIsBound = false;
}
}
public void onStartBtnClick(View view) {
Intent intent = new Intent(MainActivity.this, ExampleService.class);
startService(intent);
}
public void onStopBtnClick(View view) {
Intent intent = new Intent(MainActivity.this, ExampleService.class);
exampleService.stopService(intent);
}
答案 1 :(得分:52)
实际上,两个段落相互补充(虽然它们的措辞可能是错误的),并且两个段落都与文档中的图像一致。我们来看看:
这两条路径并非完全分开。也就是说,您可以绑定到已使用startService()启动的服务。例如,可以通过使用标识要播放的音乐的Intent调用startService()来启动背景音乐服务。之后,可能当用户想要对播放器进行一些控制或获取有关当前歌曲的信息时,活动可以通过调用bindService()绑定到服务。在这种情况下, stopService()或stopSelf()实际上不会停止服务,直到所有客户端解除绑定。
精髓是:如果你启动一个服务,然后绑定一个客户端,然后尝试停止它,服务不会在所有客户端解除绑定之前停止(销毁)。第二段并不矛盾,它改进了这一陈述。
但是,如果您选择实现onStartCommand()回调方法,则必须显式停止该服务,因为现在认为该服务已启动。在这种情况下,服务一直运行,直到服务停止使用stopSelf()或其他组件调用stopService(),无论它是否绑定到任何客户端。
这意味着:即使没有客户端绑定到它,直到明确停止,启动并绑定的服务也会运行。当然,措辞可能会更清楚一些。然而,文档中给出的生命周期图显示了这一点(我很确定我已经在“现实生活中”观察到了这一点,尽管我目前还没有直接的例子):
答案 2 :(得分:1)
是的,它有效。 我想完成一个示例代码:
我必须使用由活动启动的服务创建应用程序,活动必须调用服务中的某些方法,即使活动被杀死,服务也必须在后台运行,并且当活动重新启动时,它会避开如果服务正在运行,则重新启动服务。我希望它能帮助你,你可以看到它如何与日志一起工作。 那就是代码:
public class MyActivity extends Activity{
private MyService myService;
private boolean mIsBound = false;
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder binder) {
MyService.MyBinder b = (MyService.MyBinder) binder;
myService = b.getService();
mIsBound = true
//Do something
// Here you can call : myService.aFonctionInMyService();
}
public void onServiceDisconnected(ComponentName className) {
// Do something
mIsBound = false;
}
}
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
//Checked if my service is running
if (!isMyServiceRunning()) {
//if not, I start it.
startService(new Intent(this,MyService.class));
}
}
private boolean isMyServiceRunning() {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
for (RunningServiceInfo service : manager
.getRunningServices(Integer.MAX_VALUE)) {
if (MyService.class.getName().equals(
service.service.getClassName())) {
return true;
}
}
return false;
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
doBindService();
}
//Connection to the Service
private void doBindService() {
bindService(new Intent(this,MyService.class), mConnection,
Context.BIND_AUTO_CREATE);
}
// Disconnection from the service
private void doUnbindService() {
if (mIsBound) {
// Detach our existing connection.
unbindService(mConnection);
}
}
@Override
protected void onPause() {
// TODO Auto-generated method stub
doUnbindService();
super.onPause();
}
}
public class MyService extends Service{
public static String Tag = "MyService";
private final IBinder mBinder = new MyBinder();
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
Log.d(Tag, "onCreate()");
}
public class MyBinder extends Binder {
public LocationService getService() {
return LocationService.this;
}
}
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
Log.d(Tag, "onBind()");
return mBinder;
}
@Override
public boolean onUnbind(Intent intent) {
// TODO Auto-generated method stub
Log.d(Tag, "onUnBind()");
return super.onUnbind(intent);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
Log.d(Tag,"onStartCommand()");
return START_STICKY;
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
Log.d(Tag, "onDestroy");
super.onDestroy();
}
public void aFonctionInMyService(){
//Do Something
}
}