Android基础——Service绑定总结

这篇主要是:开发者文档的翻译和总结:


Bound Service
绑定服务允许组件(例如Activity)绑定一个Service,并可以发送请求、接受响应甚至执行进程间的通讯。


The Basic:
实现了Service类的服务,允许其他应用去绑定它并和它进行交互。这样我们必须覆盖onBind()方法。这个方法会返回一个IBinder对象,客户端可以利用这个对象和服务端进行交互。
客户端通过bindService()方法绑定服务端。当调用这个方法时,必须要提供一个ServiceConnection,用它来建立和服务端的绑定。虽然bindService()方法没有返回值,但是当Android系统建立服务端和客户端的连接时,会调用ServiceConnection对象的onServiceConnected()方法来传递一个IBinder到客户端,用于和服务端通信。
可以有多个客户端绑定到一个服务端,但是Android系统只会在第一个客户端绑定服务端时,调用service的onBind()方法去获取IBinder对象。之后系统会传递这个IBinder到绑定服务端的其他客户端(这时是不会再次调用onBind()方法的)。
如果服务不是通过startService()方法启动的,那么当最后一个客户端和服务端解绑时,系统就会摧毁掉这个服务。


Creating a Bound Service:
当创建一个服务提供绑定时,必须要提供一个IBinder对象能够让客户端和服务端进行交互的接口。有3种方式能够定义这种交互的接口:
1,Extending the Binder class:
当我们的服务是属于本应用的一部分,和应用运行在同一个进程中时,我们采用这种方式来创建这个交互的接口,继承Binder类,并在onBind()返回一个他的实例对象。这样客户端就可以接收到这个IBinder对象,并用它直接访问Binder实现类或者Service中的共有方法。
我们往往在服务仅仅作为应用的一部分运行在后台时采用这种方式。但是如果我们需要服务能被其他应用或者其他线程访问时,就不能采用这样的方法了。
2,Using Messenger:
我们采用这种方式,当我们需要跨进程通讯时。这种方式,我们需要在service中定义一个handler,用这个handler去响应不同的Message。这样一个Handler是基于Messenger的,可以通过IBinder传递到客户端,客户端可以利用这个Messenger向服务端发送命令。同样的哭护短也可以定义一个Messenger,传递给服务端让其可以发送消息回客户端。
这是一种最简便的跨进程通讯方式,使用Messenger实现时,所有的请求都被放在单一的线程中,这样服务就是线程安全的。
3,Using AIDL:
我们知道Messenger会创建一个队列用于存放所有的客户端请求在一个单一线程中,这样服务端就可以一个一个的接收请求。如果我们想要我们的服务同时处理多个请求,我们就要采用这种方式。
使用AIDL,我们需要创建.aidl文件用于定义进程间通讯的接口。AndroidSDK工具会生成实现了接口的抽象类,在service中会用到。


但部分的应用给都不需要使用AIDL来实现服务的绑定。这样做要求在多线程下,可能导致实现起来更加复杂。


Extending the Binder class:

1,在Service中,创建一个Binder的实例:(需要满足下面任意一个条件)
·包含客户端可以调用的公有方法
·返回当前的Service实例,并保证Service中有可以访问的公有方法
·返回一个service持有的其他类的实例,并保证其中有可以访问的公有方法
2,onBind()方法返回Binder的实例。
3,在客户端,通过onServiceConnection()方法接收Binder实例。


Using Messenger:

1,service要实现Handler,用于接收客户端发来的消息
2,这个Handler用于创建一个Messenger对象
3,用这个Messenger创建一个IBinder对象用于onBind()的返回
4,客户端用这个IBinder对象实例化一个Messenger,这样客户端就可以使用Messenger发送Message到service
5,服务端接收每一个Message,并在Handler中进行处理
这种方式客户端没有可以调用的服务端提供的公有方法,而是以发送消息的形式进行通信。


Binding to a Service:
绑定时异步进行的,当调用bindService()时这个方法会直接返回,是不会返回一个IBinder对象给客户端的。为了接受这个IBinder对象,客户端必须创建ServiceConnection的实例并通过它去bindservice()。ServiceConnection中有一个回调方法,系统会调用它来传递IBinder对象到客户端。
(只有activity、service、content provider可以绑定服务,broadCastReceiver是不可以的)
客户端绑定服务的步骤:
1,实现ServiceConnection:
覆盖它的两个回调方法:
·onServiceConnected()
系统调用这个方法来传递service的onBind()返回的IBinder对象
·onServiceDisconnected()
服务异常终止时系统会回调这个方法
2,调用bindService()方法,传递实现的ServiceConnection
3,当系统调用onServiceConnection()方法时,我们就可以调用服务端的方法了
4,调用unbindService()来解除绑定


Additional notes:
1,DeadObjectException会在连接中断时出现;
2,在客户端呢的生命周期中,我们一定要注意协调绑定和解除绑定的时机:
·当我们需要服务运行在activity在可见状态下时,最好在onstart()方法中绑定服务,在onStop()方法中解除绑定
·当我们需要activity能够接收到响应即使它处于不可见的停止状态,我们可以在onCreate()方法中绑定,在onDestroy()中解除绑定。这就意味着在activity的整个生命周期中都要使用服务
~通常我们不会在onResume()和onPause()方法中绑定和解绑定。因为这些回调方法再生命周期的状态转换器调用的太过频繁。例如:很多个activity绑定到了同一个service,这是由两个activity发生了状态的转换,这时当前的activity解除了绑定,service会发生销毁和再次创建,而这是并没有绑定完成。

你可能感兴趣的:(Android基础——Service绑定总结)