Bound Service

一、Creating a Bound Service

provides IBinder

1.Extending the Binder class

Service is private to your own applications and run the same process as the client; Client and service are in the   same application.

  2.Using a messenger

across different process. The Messenger creates a queue of all the client requests in a single thread, so the service receives requests one at a time.

  3.Using AIDL

Service handle  multiple requests simultaneously, then you can use AIDL directly; The service must be capable of multithreading and be built thread-safe.

Most applications should not use AIDL to create a bound service, because it may request multithreading capabilities and can result in a more complicated implementation.


二、Extending the Binder class

set up

1.In service create an instance of Binder that  either 

.contains public methods that the clients can call.
.return the current service instance, which has public methods the clients can call.
.or returns an instance of anther class hosted by the service with public methods the clients can call.

2.Return this instance of Binder from the onBind() callback method


3.In the client , receive the Binder from the onServiceConnected() callback method and make calls the bound service    using the provided.


Note: The reason the service and client must be in the same application ,is so the client can cast the returned object and   properly call its APIS.

  The service and clients  must be in the same process, because this technique does not perform any marshalling   across processes.


             例子:

Service 中

public class LocalService extends Service {

    // Binder given to clients
    private final IBinder mIBinder = new LocalBinder();

    private final Random mRandom = new Random();

    /**
     *  method for clients
     * @return
     */
    public int getRandomNumber(){
        return mRandom.nextInt(100);
    }

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


    public class LocalBinder extends Binder{
        LocalService getService(){
            // Return this instance of LocalService so the clients can call public methods
            return LocalService.this;
        }
    }
}

Client 中

public class BindingActivity extends Activity implements View.OnClickListener {

    private LocalService mLocalService;
    private boolean mBound = false;

    private Button mButton;

    // Defines the callbacks  for service binding,  passing to bindService()
    private ServiceConnection mConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            LocalService.LocalBinder binder = (LocalService.LocalBinder) service;
            mLocalService = binder.getService();
            mBound = true;

        }

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

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

        mButton = (Button) findViewById(R.id.btn_bing_service);
        mButton.setOnClickListener(this);
    }

    @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();
        if (mBound){
            unbindService(mConnection);
            mBound = false;
        }
    }

    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.btn_bing_service){
            int num = mLocalService.getRandomNumber();
            Toast.makeText(this, "number : " + num, Toast.LENGTH_SHORT).show();
        }
    }
}


三、Using a Messenger

service communicate with remote processes.

1.How to use a Messenger

.The service implements a Handler that  receives a callback for each call from client.

.The Handler  is used to create a Messenger object which is a reference to the Handler.

.The Messenger creates an IBinder that the service returns to clients from onBind();

.Clients use the IBinder to instantiate the Messenger (that references the service's Handler), which the client uses to send message objects to the service.

.The service receives each Message in the Handler -specifically in the handleMessage() method.

             In this way, there are no "methods" for the client to call on the service. Instead, the client delivers "Message"(Message      objects) that the service receives in its Handler.
例子:
Service 中
public class MessengerService extends Service {
    public static final int MSG_FROM_CLIENTS = 1;

    // Target we publish for clients to send message to IncomingHandler
    private final Messenger mMessenger = new Messenger(new IncomingHandler(this));


    /**
     *  When binding to the service, we return an interface  to our messenger
     *  for sending message to the service
     * @param intent
     * @return
     */
    @Override
    public IBinder onBind(Intent intent) {
        Toast.makeText(this, "binding", Toast.LENGTH_SHORT).show();
        return  mMessenger.getBinder();
    }


    /**
     *  Handler for incoming message form clients
     */
    private static class IncomingHandler extends Handler{

        private WeakReference<Context> mReference;
        private Context mContext;

        public IncomingHandler(Context context){
            mReference = new WeakReference<>(context);
            mContext = mReference.get();
        }
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what){
                case MSG_FROM_CLIENTS:
                    Log.i("yxh", "messenger service  handle message");
                    Toast.makeText(mContext, "hello !", Toast.LENGTH_SHORT).show();
                    break;
                default:
                    super.handleMessage(msg);
                    break;
            }
        }
    }
}

Client 中
public class MessengerActivity extends Activity implements View.OnClickListener {

    // Messenger for communicating with the service;
    private Messenger mService;

    private boolean mBound;

    private Button mButton;

    private ServiceConnection mConnection  = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mService = new Messenger(service);
            mBound = true;
        }

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

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

        mButton = (Button) findViewById(R.id.btn_bing_service);
        mButton.setOnClickListener(this);
    }

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

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

    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.btn_bing_service){
            sayHello();
        }
    }

    private void sayHello(){
        if (!mBound) return;
                 Message msg = Message.obtain(null, MessengerService.MSG_FROM_CLIENTS, 0, 0);
        try {
            Log.i("yxh", "messenger send");
            mService.send(msg);
        } catch (DeadObjectException e){
            e.printStackTrace();
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }
}

四.Binding Service

Only  activities , services, and content provider can bind to a service, cannot bind to service from a broadcast receiver.

     To bind to a service from client.

1.Implement ServiceConnection.

override two callback methods
    onServiceConnected()
the system call this to deliver the IBinder returned by the service's onBind() method.
    onServiceDisconnected()
the Android system calls this when connection to the service is unexpectedly lost, such as the service has crashed or has been killed. This is not called when the clients 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                    methods defined by the interface.

       4.To disconnect from the service call unbindService().


五、 Additional notes

1. You should always trap DeadObjection exception, which are thrown when the connection has broken.

2.Objects are reference counted across processes.

3.Pair the binding and unbinding matching bring-up and tear_down moments of client's lifecycle.

(1). If you only need to interact with the service while your activity is visible, you should bind during onStart() and unbind during onStop().
(2).If you want your activity to receive responses even while it is stopped in the background then you can bind during onCreat() and unbind onDestroy().

Note: should usually not bind and unbind  during your activity's onResume() and onPause(). Because these callbacks occur at every lifecycle.




发布了58 篇原创文章 · 获赞 20 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/yxhuang2008/article/details/51235863
今日推荐