Android 绑定类型服务---绑定服务

应用程序组件(客户端)通过调用bindService()方法能够绑定服务,然后Android系统会调用服务的onBind()回调方法,这个方法会返回一个跟服务端交互的IBinder对象。

这个绑定是异步的,bindService()方法立即返回,并且不给客户端返回IBinder对象。要接收IBinder对象,客户端必须创建一个ServiceConnection类的实例,并且把这个实例传递给bindService()方法。ServiceConnection对象包含了一个系统调用的传递IBinder对象的回调方法。

注意:只有Activity、Service、和内容提供器(content provider)能够绑定服务---对于广播接收器不能绑定服务。

因此,要在客户端绑定一个服务,必须做以下事情:

1.  实现ServiceConnection抽象类

你的实现必须重写以下两个回调方法:

onServiceConnected()

    系统会调用这个方法来发送由服务的onBind()方法返回的IBinder对象。

onServiceDisconnected()

     Android系统会在连接的服务突然丢失的时候调用这个方法,如服务崩溃时或被杀死时。在客户端解除服务绑定时不会调用这个方法。

2.  调用bindService()方法来传递ServiceConnection类的实现;

3.  当系统调用你的onServiceConnected()回调方法时,你就可以开始使用接口中定义的方法来调用服务了;

4.  调用unbindService()方法断开与服务的连接。

当客户端销毁时,它将于服务端解绑,但是当你完成与服务端的交互或Activity暂停时,你应该主动的与服务端解绑,以便服务能够在不使用的时候关掉。(绑定和解绑的时机会在稍后进行更多的讨论)。

例如,以下代码片段演示了把客户端连接到由继承Binder类创建服务,它所做的所有事情就是把服务端返回的IBinder对象转换成LocalService类,并且请求LocalService实例:

LocalService mService;
private ServiceConnection mConnection = new ServiceConnection() {
    // Called when the connection with the service is established
    public void onServiceConnected(ComponentName className, IBinder service) {
        // Because we have bound to an explicit
        // service that is running in our own process, we can
        // cast its IBinder to a concrete class and directly access it.
        LocalBinder binder = (LocalBinder) service;
        mService = binder.getService();
        mBound = true;
    }

    // Called when the connection with the service disconnects unexpectedly
    public void onServiceDisconnected(ComponentName className) {
        Log.e(TAG, "onServiceDisconnected");
        mBound = false;
    }
};

用这个ServiceConnection类,客户端能够把它传递给bindService()方法来实现与服务端的绑定,如:

Intent intent = new Intent(this, LocalService.class);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);

1. bindService方法的第一个参数是一个Intent对象,它明确的命名要绑定的服务(虽然Intent能够隐含的指定);

2. 第二个参数是ServiceConnection对象;

3. 第三个参数是指明绑定选项的标识。通常它应该使用BIND_AUTO_CREATE,以便在服务不存在的时候创建这个服务。其他可能的值是BIND_DEBUG_UNBIND和BIND_NOT_FOREGROUND,或是什么都没有的“0”。

posted @ 2012-02-28 19:55  andriod2012  阅读(4055)  评论(0编辑  收藏  举报