绑定服务

绑定服务是客户端-服务器接口中的服务器。绑定服务可让组件(例如 Activity)绑定到服务、发送请求、接收响应,甚至执行进程间通信 (IPC)。 绑定服务通常只在为其他应用组件服务时处于活动状态,不会无限期在后台运行。

绑定服务是 Service类的实现,可让其他应用与其绑定和交互。要提供服务绑定,您必须实现 onBind()回调方法。该方法返回的 IBinder
对象定义了客户端用来与服务进行交互的编程接口。

 public class LocalService extends Service {

    private IBinder mBind=new LocalBinder();
    /**
     * 返回的 IBinder 对象定义了客户端用来与服务进行交互的编程接口
     */
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return mBind;
    }

    /**
     * LocalBinder 为客户端提供 getService() 方法,以检索 LocalService 的当前实例
    */
    public class LocalBinder extends Binder{
        LocalService getService(){
            return LocalService.this;
        }
    }

    public void getLog(){
        Log.d("TAG", "getLog: 我是LocalService的log");
    }
}

客户端可通过调用 [bindService()](https://developer.android.com/reference/android/content/Context.html?hl=zh-cn#bindService(android.content.Intent, android.content.ServiceConnection, int))绑定到服务。调用时,它必须提供 ServiceConnection的实现,后者会监控与服务的连接。[bindService()](https://developer.android.com/reference/android/content/Context.html?hl=zh-cn#bindService(android.content.Intent, android.content.ServiceConnection, int))方法会立即无值返回,但当 Android 系统创建客户端与服务之间的连接时,会对 ServiceConnection
调用 [onServiceConnected()](https://developer.android.com/reference/android/content/ServiceConnection.html?hl=zh-cn#onServiceConnected(android.content.ComponentName, android.os.IBinder)),向客户端传递用来与服务通信的 IBinder。

public class MainActivity extends AppCompatActivity {
    LocalService service;
    boolean mBound = false;
    private ServiceConnection mConnection = new ServiceConnection() {
       @Override
        public void onServiceConnected(ComponentName name, IBinder iBinder) {
            LocalService.LocalBinder binder = (LocalService.LocalBinder) iBinder;
            service = binder.getService();
            service.getLog();
            mBound = true;
        }

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

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

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

    @Override
    protected void onStop() {
        super.onStop();
        if (mBound) {
            unbindService(mConnection);
            mBound = false;
        }
    }
}

使用 Messenger

与 AIDL 比较

当您需要执行 IPC 时,为您的接口使用Messenger要比使用 AIDL 实现它更加简单,因为 Messenger会将所有服务调用排入队列,而纯粹的 AIDL 接口会同时向服务发送多个请求,服务随后必须应对多线程处理。
对于大多数应用,服务不需要执行多线程处理,因此使用 Messenger可让服务一次处理一个调用。如果您的服务必须执行多线程处理,则应使用 AIDL 来定义接口。

如需让服务与远程进程通信,则可使用 Messenger 为您的服务提供接口。利用此方法,您无需使用 AIDL 便可执行进程间通信 (IPC)。

  • 服务实现一个 Handler,由其接收来自客户端的每个调用的回调

  • Handler用于创建 Messenger对象(对 Handler的引用)

  • Messenger创建一个 IBinder,服务通过 onBind()使其返回客户端

    public class MessengerService extends Service {
      /** Command to the service to display a message */
      static final int MSG_SAY_HELLO = 1;
    
      /**
       * Handler of incoming messages from clients.
       */
      class IncomingHandler extends Handler {
          @Override
          public void handleMessage(Message msg) {
              switch (msg.what) {
                  case MSG_SAY_HELLO:
                      Toast.makeText(getApplicationContext(), "hello!", Toast.LENGTH_SHORT).show();
                      break;
                  default:
                      super.handleMessage(msg);
              }
          }
      }
    
      /**
       * Target we publish for clients to send messages to IncomingHandler.
       */
      final Messenger mMessenger = new Messenger(new IncomingHandler());
    
      /**
       * 绑定到服务时,我们返回一个接口给我们的messenger为服务发送消息。
       */
      @Override
      public IBinder onBind(Intent intent) {
          Toast.makeText(getApplicationContext(), "binding", Toast.LENGTH_SHORT).show();
          return mMessenger.getBinder();
      }
     }
    
  • messenger类方法
    public IBinder getBinder() {
    return mTarget.asBinder();
    }
    public Messenger(Handler target) {
    mTarget = target.getIMessenger();
    }

客户端只需根据服务返回的IBInder创建一个 Messenger,然后利用 send()发送一条消息。

public class ActivityMessenger extends Activity {
    /** Messenger for communicating with the service. */
    Messenger mService = null;

    /** Flag indicating whether we have called bind on the service. */
    boolean mBound;

    /**
     * Class for interacting with the main interface of the service.
     */
    private ServiceConnection mConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className, IBinder service) {
            // This is called when the connection with the service has been
            // established, giving us the object we can use to
            // interact with the service.  We are communicating with the
            // service using a Messenger, so here we get a client-side
            // representation of that from the raw IBinder object.
            mService = new Messenger(service);
            mBound = true;
        }

        public void onServiceDisconnected(ComponentName className) {
            // This is called when the connection with the service has been
            // unexpectedly disconnected -- that is, its process crashed.
            mService = null;
            mBound = false;
        }
    };

    public void sayHello(View v) {
        if (!mBound) return;
        // Create and send a message to the service, using a supported 'what' value
        Message msg = Message.obtain(null, MessengerService.MSG_SAY_HELLO, 0, 0);
        try {
            mService.send(msg);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

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

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

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

管理绑定服务的生命周期

当服务与所有客户端之间的绑定全部取消时,Android 系统便会销毁服务(除非还使用 [onStartCommand()](https://developer.android.com/reference/android/app/Service.html?hl=zh-cn#onStartCommand(android.content.Intent, int, int))启动了该服务)。因此,如果您的服务是纯粹的绑定服务,则无需对其生命周期进行管理 — Android 系统会根据它是否绑定到任何客户端代您管理。
不过,如果您选择实现 [onStartCommand()](https://developer.android.com/reference/android/app/Service.html?hl=zh-cn#onStartCommand(android.content.Intent, int, int))回调方法,则您必须显式停止服务,因为系统现在已将服务视为已启动。在此情况下,服务将一直运行到其通过 stopSelf()自行停止,或其他组件调用 stopService()为止,无论其是否绑定到任何客户端。
此外,如果您的服务已启动并接受绑定,则当系统调用您的 onUnbind()方法时,如果您想在客户端下一次绑定到服务时接收 onRebind()调用,则可选择返回 true。onRebind() 返回空值,但客户端仍在其 [onServiceConnected()](https://developer.android.com/reference/android/content/ServiceConnection.html?hl=zh-cn#onServiceConnected(android.content.ComponentName, android.os.IBinder))
回调中接收 IBinder。

绑定服务_第1张图片
生命周期

你可能感兴趣的:(绑定服务)