一、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
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
1.In service create an instance of Binder that either
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
1.How to use a Messenger
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;
}
}
}
}
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.1.Implement ServiceConnection.