startService()只在创建时执行一次onCreate()、onStartCommand(),多次调用startService,该Service只能被创建一次,即该Service的onCreate方法只会被调用一次。但是每次调用startService,onStartCommand方法都会被调用。Service的onStart方法在API 5时被废弃,替代它的是onStartCommand方法。
当执行stopService()时,直接调用onDestroy()。调用者如果没有stopService(),Service会一直在后台运行,下次调用者再起来仍然可以stopService()。
执行bindService()时,这个时候调用者和Service绑定在一起。调用者调用unbindService方法或者调用者Context不存在了(如Activity被finish了),Service就会调用onUnbind->onDestroy。这里所谓的绑定在一起就是说两者共存亡了。
第一次执行bindService时,onCreate和onBind方法会被调用,但是多次执行bindService时,onCreate和onBind方法并不会被多次调用,即并不会多次创建服务和绑定服务。unBindService()只能调用一次,否则会造成ServiceConnection泄露。
注意:
即使调用了unBindService方法解除了绑定,我们却依旧可以调用服务中的方法。
多次绑定服务会出现什么现象?
多次绑定服务,服务只会被创建一次,oncreate方法只会被执行一次
多次绑定服务,onBind方法不会被重复调用
startService()不能调用Service的方法,因为它不执行onBind()
onBind回调方法将返回给客户端一个IBinder接口实例,IBinder允许客户端回调服务的方法,比如得到Service运行的状态或其他操作。我们需要IBinder对象返回具体的Service对象才能操作,所以说具体的Service对象必须首先实现Binder对象。
操作演示
脱离了Service的体系,不能用new 对象(要用通过“中间人”IBinder去调用Service的方法)的方式去调用Service的方法:
注意:onBind()必须要由返回值,否则ServiceConnection()中的回调方法不会执行
/*
* onBind() 是 Service 的虚方法,因此我们不得不实现它。
* 返回 null,表示客服端不能建立到此服务的连接。
* */
@Override
public IBinder onBind(Intent intent) {
Log.e(TAG, "onBind: ");
return new MyBinder();
}
public class MyBinder extends Binder {
// 模拟一个方法
public void show() {
Toast.makeText(ServiceLifecycle.this, "我是Service的show方法", Toast.LENGTH_SHORT).show();
}
}
在对应的回调方法中调用Service模拟的show方法
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.e(TAG, "onServiceConnected: ");
// 拿到onBind()中返回的Binder,调用其方法
binder = ((ServiceLifecycle.MyBinder) service);
binder.show();
}
本地服务依附在主进程上,在一定程度上节约了资源。本地服务因为是在同一进程,因此不需要IPC,也不需要AIDL。相应bindService会方便很多。缺点是主进程被kill后,服务变会终止。
远程服务是独立的进程,对应进程名格式为所在包名加上你指定的android:process字符串。由于是独立的进程,因此在Activity所在进程被kill的时候,该服务依然在运行。缺点是该服务是独立的进程,会占用一定资源,并且使用AIDL进行、IPC稍微麻烦一点。
对于startService来说,不管是本地服务还是远程服务,我们需要做的工作都一样简单。
https://blog.csdn.net/biezhihua/article/details/44439897#%E7%AC%AC%E4%B8%80%E7%A7%8D
startService()启动的服务是可见的
bindService()绑定的服务是隐藏的