Android Services 创建一个Bound服务

来源:互联网 发布:算法 第四版 微盘 编辑:程序博客网 时间:2024/05/21 22:40

原文地址: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来为服务创建接口。在这种方式下,服务定义一个响应各类消息对象Message的Handler。此Handler是Messenger与客户端共享同一个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(null0));
                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(null1);
        // 设置回调用的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, "回调成功");
        }
          
    };
}


0 0
原创粉丝点击