Android Services 创建一个Bound服务

原文地址:http://www.android-doc.com/guide/components/bound-services.html

创建一个Bound服务


bound服务是 Service 类的一种实现,它允许其它应用程序与其绑定并交互。为了让服务支持绑定,你必须实现 onBind() 回调方法。这个方法返回一个 IBinder 对象,此对象定义了客户端与服务进行交互时所需的编程接口。


当你实现自己的bound服务时,最重要的工作就是定义 onBind() 回调方法所返回的接口。定义服务 IBinder 接口的方式有好几种。

创建一个支持绑定的服务时,你必须提供一个 IBinder ,用作客户端和服务间进行通信的编程接口。定义这类接口的方式有三种:


扩展Binder类
如果服务是你的应用程序所私有的,并且与客户端运行于同一个进程中(通常都是如此),你应该通过扩展 Binder类来创建你的接口,并从 onBind()返回一个它的实例。客户端接收该 Binder对象并用它来直接访问 Binder甚至 Service中可用的公共(public)方法。
如果你的服务只是为你自己的应用程序执行一些后台工作,那这就是首选的技术方案。不用这种方式来创建接口的理由只有一个,就是服务要被其它应用程序使用或者要跨多个进程使用。
使用Messenger
如果你需要接口跨越多个进程进行工作,可以通过 Messenger来为服务创建接口。在这种方式下,服务定义一个响应各类消息对象 MessageHandler。此 HandlerMessenger与客户端共享同一个 IBinder的基础,它使得客户端可以用消息对象 Message向服务发送指令。此外,客户端还可以定义自己的 Message,以便服务能够往回发送消息。
这是执行进程间通信(IPC)最为简便的方式,因为 Messenger 会把所有的请求放入一个独立进程中的队列,这样你就不一定非要把服务设计为线程安全的模式了。
使用AIDL
Android接口定义语言AIDL(Android Interface Definition Language)完成以下的所有工作:将对象解析为操作系统可识别的原始形态,并将它们跨进程 序列化(marshal)以完成IPC。前一个使用 Messenger的方式,实际上也是基于AIDL的,它用AIDL作为底层结构。如上所述, Messenger将在一个单独的进程中创建一个包含了所有客户端请求的队列,这样服务每次就只会收到一个请求。可是,如果想让你的服务能同时处理多个请求,那你就可以直接使用AIDL。这种情况下,你的服务必须拥有多线程处理能力,并且是以线程安全的方式编写的。
要直接使用AIDL,你必须创建一个 .aidl文件,其中定义了编程的接口。Android SDK 工具使用此文件来生成一个抽象类(abstract class),其中实现了接口及对IPC的处理,然后你就可以在自己的服务中扩展该类。

注意: 绝大多数应用程序都不应该用AIDL来创建bound服务,因为这可能需要多线程处理能力并且会让代码变得更为复杂。 因此,AIDL对绝大多数应用程序都不适用,并且本文也不会讨论如何在服务中使用它的内容。如果你确信需要直接使用AIDL,那请参阅 AIDL 文档。




使用Messenger 的例子:

首先是服务端。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public  class  MessengerTestService  extends  Service {
  
     protected  static  final  String TAG =  "MessengerTestService" ;
      
     private  Handler mHandler =  new  Handler() {
         @Override
         public  void  handleMessage(Message msg) {
             switch  (msg.what) {
             case  1 :
                 Log.d(TAG,  "收到消息" );
                  //获取客户端message中的Messenger,用于回调
                 final  Messenger callback = msg.replyTo;
                 try  {
                     // 回调
                     callback.send(Message.obtain( null 0 ));
                 catch  (RemoteException e) {
                     // TODO Auto-generated catch block
                     e.printStackTrace();
                 }
                 break ;
             }
         }
     };
      
     @Override
     public  IBinder onBind(Intent intent) {
         return  new  Messenger(mHandler).getBinder();
     }
  
}



然后是客户端

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
public  class  MainActivity  extends  Activity {
  
     protected  static  final  String TAG =  "MainActivity" ;
     Messenger messenger;
     Messenger reply;
      
     @Override
     protected  void  onCreate(Bundle savedInstanceState) {
         super .onCreate(savedInstanceState);
         setContentView(R.layout.activity_main);
         reply =  new  Messenger(handler);
         Intent intent =  new  Intent();
         intent.setClassName( "test.messenger" "test.messenger.MessengerTestService" );
          
         // 绑定服务
         bindService(intent,  new  ServiceConnection() {
              
             @Override
             public  void  onServiceDisconnected(ComponentName name) {
                  
             }
              
             @Override
             public  void  onServiceConnected(ComponentName name, IBinder service) {
                 Toast.makeText(MainActivity. this "bind success" 0 ).show();
                 messenger =  new  Messenger(service);
             }
         }, Context.BIND_AUTO_CREATE);
          
     }
  
     public  void  sendMessage(View v) {
         Message msg = Message.obtain( null 1 );
         // 设置回调用的Messenger
         msg.replyTo = reply;
         try  {
             messenger.send(msg);
         catch  (RemoteException e) {
             e.printStackTrace();
         }
     }
      
     private  Handler handler =  new  Handler() {
  
         @Override
         public  void  handleMessage(Message msg) {
             Log.d(TAG,  "回调成功" );
         }
          
     };
}


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值