Bound Services

阅读:http://developer.android.com/guide/components/bound-services.html

A bound service is an implementation of the Service class that allows other applications to bind to it and interact with it. To provide binding for a service, you must implement the onBind()callback method. This method returns an IBinder object that defines the programming interface that clients can use to interact with the service.

A client can bind to the service by calling bindService(). When it does, it must provide an implementation of ServiceConnection, which monitors the connection with the service. The bindService()method returns immediately without a value, but when the Android system creates the connection between the client and service, it calls onServiceConnected() on the ServiceConnection, to deliver theIBinder that the client can use to communicate with the service.

Multiple clients can connect to the service at once. However, the system calls your service's onBind() method to retrieve theIBinder only when the first client binds. The system then delivers the same IBinder to any additional clients that bind, without callingonBind() again.

When the last client unbinds from the service, the system destroys the service (unless the service was also started bystartService()).

必须实现onBind()接口,这个接口用来返回一个IBinder,使得client能够通过它来通信。

而client也应该通过bindService()来实现绑定,但必须同时实现ServiceConnection的onServiceConnected(),以此来实现两者的连接。

不同的组件都可以绑定,但是只有第一个组件进行绑定的时候会进行onBind,当有更多的组件绑定时,直接返回service实例。

如果最后无组件绑定,那么该service被系统摧毁。


提供IBind的方法之一:继承Binder class

如果你的service只是提供给自己用,那么可以使用该方法。

首先要记得:1、在onBind返回service;2、client方法将会从onServiceConnected中获得IBind;3、提供一些公开的方法供client使用

public class LocalService extends Service {
    // Binder given to clients
    private final IBinder mBinder = new LocalBinder();
    // Random number generator
    private final Random mGenerator = new Random();

    /**
     * Class used for the client Binder.  Because we know this service always
     * runs in the same process as its clients, we don't need to deal with IPC.
     */
    public class LocalBinder extends Binder {
        LocalService getService() {
            // Return this instance of LocalService so clients can call public methods
            return LocalService.this;
        }
    }

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

    /** method for clients */
    public int getRandomNumber() {
      return mGenerator.nextInt(100);
    }
}
public class BindingActivity extends Activity {
    LocalService mService;
    boolean mBound = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }

    @Override
    protected void onStart() {
        super.onStart();
        // Bind to LocalService
        Intent intent = new Intent(this, LocalService.class);
        bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
    }

    @Override
    protected void onStop() {
        super.onStop();
        // Unbind from the service
        if (mBound) {
            unbindService(mConnection);
            mBound = false;
        }
    }

    /** Called when a button is clicked (the button in the layout file attaches to
      * this method with the android:onClick attribute) */
    public void onButtonClick(View v) {
        if (mBound) {
            // Call a method from the LocalService.
            // However, if this call were something that might hang, then this request should
            // occur in a separate thread to avoid slowing down the activity performance.
            int num = mService.getRandomNumber();
            Toast.makeText(this, "number: " + num, Toast.LENGTH_SHORT).show();
        }
    }

    /** Defines callbacks for service binding, passed to bindService() */
    private ServiceConnection mConnection = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName className,
                IBinder service) {
            // We've bound to LocalService, cast the IBinder and get LocalService instance
            LocalBinder binder = (LocalBinder) service;
            mService = binder.getService();
            mBound = true;
        }

        @Override
        public void onServiceDisconnected(ComponentName arg0) {
            mBound = false;
        }
    };
}

整个绑定的过程就是,通过bindService()绑定service(通过unbindService(mConnection)解绑定),那么service的onbind就会返回一个IBind对象,然后继承ServiceConnection类重写该类的onServiceConnected()、onServiceDisconnected()方法,可以从onServiceConnected获得IBind对象,实现两者的绑定。当client被摧毁的时候,绑定就结束了。

bindService(intent, mConnection, Context.BIND_AUTO_CREATE)的第三个参数有BIND_AUTO_CREATE 、 BIND_DEBUG_UNBIND 、BIND_NOT_FOREGROUND三种选择。


You should usually pair the binding and unbinding during matching bring-up and tear-down moments of the client's lifecycle. For example:

  • If you only need to interact with the service while your activity is visible, you should bind during onStart() and unbind during onStop().
  • If you want your activity to receive responses even while it is stopped in the background, then you can bind during onCreate() and unbind during onDestroy(). Beware that this implies that your activity needs to use the service the entire time it's running (even in the background), so if the service is in another process, then you increase the weight of the process and it becomes more likely that the system will kill it.

Note: You should usually not bind and unbind during your activity's onResume() and onPause(), because these callbacks occur at every lifecycle transition and you should keep the processing that occurs at these transitions to a minimum. Also, if multiple activities in your application bind to the same service and there is a transition between two of those activities, the service may be destroyed and recreated as the current activity unbinds (during pause) before the next one binds (during resume). (This activity transition for how activities coordinate their lifecycles is described in the Activities document.)

  如果你需要在Activity可见的时候绑定,那么就在onStart的时候绑定在onStop的时候解绑定。

  如果就算Activity在后台也能绑定,那就在onCreate绑定,onDestroy的时候解绑定。


如果选择实现绑定service的onStartCommand()方法,那么记得明确地结束service。

最后,bound service的生命周期:

posted @ 2013-10-21 22:14  yutoulck  阅读(217)  评论(0编辑  收藏  举报