Service官方教程(9)绑定服务时的注意事项

Binding to a Service

  Application components (clients) can bind to a service by calling bindService(). The Android system then calls the service's onBind() method, which returns an IBinder for interacting with the service.

  The binding is asynchronous. bindService() returns immediately and does not return the IBinder to the client. To receive the IBinder, the client must create an instance of ServiceConnection and pass it to bindService(). The ServiceConnection includes a callback method that the system calls to deliver the IBinder.

  Note: Only activities, services, and content providers can bind to a service—you cannot bind to a service from a broadcast receiver.

So, to bind to a service from your client, you must:

  1. Implement ServiceConnection.

    Your implementation must override two callback methods:

    onServiceConnected()
    The system calls this to deliver the IBinder returned by the service's onBind() method.
    onServiceDisconnected()
    The Android system calls this when the connection to the service is unexpectedly lost, such as when the service has crashed or has been killed. This is not called when the client unbinds.
  2. Call bindService(), passing the ServiceConnection implementation.
  3. When the system calls your onServiceConnected() callback method, you can begin making calls to the service, using the methods defined by the interface.
  4. To disconnect from the service, call unbindService().

    If your client is still bound to a service when your app destroys the client, destruction causes the client to unbind. It is better practice to unbind the client as soon as it is done interacting with the service. Doing so allows the idle service to shut down. For more information about appropriate times to bind and unbind, see Additional Notes.

  For example, the following snippet connects the client to the service created above by extending the Binder class, so all it must do is cast the returned IBinder to the LocalService class and request the LocalService instance:

 1 LocalService mService;
 2 private ServiceConnection mConnection = new ServiceConnection() {
 3     // Called when the connection with the service is established
 4     public void onServiceConnected(ComponentName className, IBinder service) {
 5         // Because we have bound to an explicit
 6         // service that is running in our own process, we can
 7         // cast its IBinder to a concrete class and directly access it.
 8         LocalBinder binder = (LocalBinder) service;
 9         mService = binder.getService();
10         mBound = true;
11     }
12 
13     // Called when the connection with the service disconnects unexpectedly
14     public void onServiceDisconnected(ComponentName className) {
15         Log.e(TAG, "onServiceDisconnected");
16         mBound = false;
17     }
18 };

  With this ServiceConnection, the client can bind to a service by passing it to bindService(). For example:

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

Additional notes 注意事项

  Here are some important notes about binding to a service:

  • You should always trap DeadObjectException exceptions, which are thrown when the connection has broken. This is the only exception thrown by remote methods.
    捕获DeadObjectException异常
  • Objects are reference counted across processes.
    进程间对象是 引用+引用计数 访问。
  • 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.
      绑定与解绑成对出现,注意组件的生命周期。通常可以在onCreate中绑定,onDestory解绑.而不要在onResume,onPause中绑定,解绑。

    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.)

  For more sample code, showing how to bind to a service, see the RemoteService.java class in ApiDemos.

 

posted @ 2016-09-23 17:06  f9q  阅读(259)  评论(0编辑  收藏  举报