A bound Service 提供了一种CS模式的Service。
A bound service allows components (such as activities) to bind to the service, send requests, receive responses, and even perform interprocess communication

Server--Extend a Service, 然后实现onBind()方法,返回IBinder对象。
Client--bindService(),然后必须实现ServiceConnection接口,其具有两个方法,onServiceConnected(),可通知连接服务的状态,并返回IBinder对象。
其中onBinder只在第一次服务被连接时才会被调用,之后将直接返回IBinder对象。
当最后一个client unbind时,系统将destroy 该Service.

Creating a Bound Service

  • 继承Binder类
    然后将它的一个实例作为onBind()返回值。适用于Server和Client在同一进程内。

创建Server

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);    }}

Tip: 在LocalBinder中提供了getService()方法,使得客户端可以获得Service的实例,这样就可以调用Service的公共方法。

Client调用:

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;        }    };}

可注意到Service的bind,使用以及unBind()的使用。

  • 使用Messenger
    在Service中Create 一个Handler,然后可以接收和处理不同的Message type,同时Messenger 也可返回一个IBinder对象给客户端。此外,客户端也可定义自己的Messenger,然后Service可以发送Message以便返回结果。最简单的实现IPC通信。适用于跨进程。
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());    /**     * When binding to the service, we return an interface to our messenger     * for sending messages to the service.     */    @Override    public IBinder onBind(Intent intent) {        Toast.makeText(getApplicationContext(), "binding", Toast.LENGTH_SHORT).show();        return mMessenger.getBinder();    }}

以下是Messenger的定义

Reference to a Handler, which others can use to send messages to it. This allows for the implementation of message-based communication across processes, by creating a Messenger pointing to a Handler in one process, and handing that Messenger to another process.

意思是它是对Handler的引用,其他组件可通过它发送消息到handler。允许基于message的handle IPC。它是对Binder的简单包装。

Client 调用

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;        }    }}

就是一个事件传递。

  • 使用AIDL
    上个使用Messenger的方式,底层结构也是使用AIDL。但Messenger则只是依次处理。但若想同时处理,直接使用AIDL。适用于跨进程。

Tip: 大部分应用无需使用AIDL来创建bound service, 它可能需要多线程处理能力以及更复杂的实现。


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

bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
第三个参数BIND_AUTO_CREATE指create service if its not already alive. 还可以是BIND_DEBUG_UNBIND, BIND_NOT_FOREGROUD, 或者0。

建议:you should bind during onStart() and unbind during onStop().如果希望在App可见时。
若想在activity接收响应在stopped时候,可bind during onCreate() and unbind during onDestroy().

更多相关文章

  1. Android Studio sync 失败解决方法
  2. Android全屏的两种方法
  3. Android PackageManager 卸载包的方法
  4. Android实现定时器的方法
  5. Android播放音乐方法
  6. 阻止dialog消失的方法 (Android Platform)
  7. Android中的多种文件读写操作方法

随机推荐

  1. Android事件分发机制——View(一)
  2. Android:TabLayout向上滑动停留页面顶部
  3. Android点击WebView中的图片查看大图
  4. Android——Framework Resource添加使用
  5. 【Android动画九章】-AlphaAnimation(渐变
  6. 简单介绍安卓的五大布局
  7. Android在一个app中启动其他app中的servi
  8. 新版Cordova(>4.0)编译Android(安卓)APK
  9. 关于Android(安卓)webview 的cookie同步
  10. Android(安卓)自定义viewpager选中点