可跳过
现在是4-8号凌晨,坐在广州火车站旁边的麦当劳里面,和三个小偷+一个主动跟小偷唠嗑的傻妹子。前几天请假回学校去答辩,以为8号要上班,买了七号晚上回来的机票,可惜到广州的时候没有车到惠州的,得在广州站等到8号早上4点坐火车去惠州。昨天晚上坐在去广州火车站的大巴车上吧,沿途看着陌生的街道和行人,有种不可描述的开心,像小鱼游进了更大的鱼塘。我喜欢这里,可能是因为这里看起来充满了机会,也可能是因为经常被叫作“靓仔”。坐在这里好困,又不敢睡觉,万一三个小偷趁我睡着了把我拐走怎么办,困得不行的时候想到不如写简书吧,那就开始写吧!
Service的绑定和启动有什么区别?
好像跳过了什么内容,应该先说怎么启动或者绑定一个Service吧?
启动一个Service
通过Context的startService(intent)方法便可以开启Service,这样一来只要是Context的子类或拥有Context引用的对象都可以开启Service了,上回说到Service的生命周期,这里通过startService开启Service之后会回调...(略),启动一个Service之后,这个Service可以说跟启动它的对象都没关系了,各玩各的,即便是启动它的对象都没了(比如Activity都finish掉了),启动的Service里面开的线程还在那儿玩,通过在onStartCommand里面开线程打印内容就能看到这个现象。
绑定Service
上面启动Service会看到各玩各的情况,但是如果我们使用绑定Service的方式,就可以获得一个与Service通信的通道,这个通道可能是简单的Binder子类,也可能是使用AIDL描述过的一个接口,AIDL涉及到跨进程通信,后面再看,我们先来说简单的Binder子类吧。Binder是实现了IBinder接口的类,我们写一个类继承Binder的话不需要实现任何方法,只需要写自己需要的方法,然后onBind方法返回自己写的类的对象就行了,比如这样写:
public class MyBinder extends Binder {
public MyService getService() {
return MyService.this;
}
}
public IBinder onBind(Intent intent) {
Log.d(TAG, "onBind: ");
return new MyBinder();
}
这样一来,我们只要获得返回的这个MyBinder的对象就能获得当前的MyService对象,就能使用它的方法了。那这个MyBinder对象返回到哪里去了呢?到这里来了:
private ServiceConnection mServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
MyService.MyBinder myBinder = (MyService.MyBinder) service;
Log.d(TAG, "onServiceConnected: " + myBinder.getService().func());
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.d(TAG, "onServiceDisconnected: ");
}
};
private void bind() {
this.bindService(new Intent(this, MyService.class), mServiceConnection, BIND_AUTO_CREATE);
}
我们在使用bindService方法来绑定一个Service的时候,第二个参数是一个ServiceConnection的实体类。第三个参数是设置在绑定成功的时候创建Service对象,这里主要说ServiceConnection。我们自己写了一个ServiceConnection的实现类,其中需要重写两个方法,onServiceConnected和onServiceDisconnected,其中:
- onServiceConnected(ComponentName name, IBinder service)
第一个参数是绑定的Service的包名,第二个参数就是Service里面的onBind方法返回的MyBinder对象,我们在方法体里面把这个IBinder对象向下转型为MyBinder对象就可以调用里面的getService方法获得启动的MyService对象啦 - onServiceDisconnected(ComponentName name)
这个方法是启动的Service还在,但是启动这个Service的组件挂掉了被迫断开连接的时候回调,比如启动Service的这个组件的进程被销毁的时候。
二者区别
好了,把上面两种说出来之后两者的区别也出来了,通过startService启动Service之后不能调用到Service里面的方法,但是bindService就可以通过获得一个Binder对象,即与Service通信的通道。