使用RemoteService. 在RemoteService 中调用RemoteServiceCallback.
/**
* This is a list of callbacks that have been registered with the
* service. Note that this is package scoped (instead of private) so
* that it can be accessed more efficiently from inner classes.
*/
final RemoteCallbackList<IRemoteServiceCallback> mCallbacks
= new RemoteCallbackList<IRemoteServiceCallback>();
实现IRemoteServiceCallback接口
/**
* This implementation is used to receive callbacks from the remote service.
*/
private IRemoteServiceCallback mCallback = new IRemoteServiceCallback.Stub() {
/**
* This is called by the remote service regularly to tell us about new
* values. Note that IPC calls are dispatched through a thread pool
* running in each process, so the code executing here will NOT be
* running in our main thread like most other things -- so, to update
* the UI, we need to use a Handler to hop over there.
*/
public void valueChanged(int value) {
mHandler.sendMessage(mHandler.obtainMessage(BUMP_MSG, value, 0));
}
};
HandleMessage
/**
* Our Handler used to execute operations on the main thread. This is used
* to schedule increments of our value.
*/
private final Handler mHandler = new Handler() {
@Override public void handleMessage(Message msg) {
switch (msg.what) {
// It is time to bump the value!
case REPORT_MSG: {
// Up it goes.
int value = ++mValue;
// Broadcast to all clients the new value.
final int N = mCallbacks.beginBroadcast();
Log.v(TAG, "N = " + N );
for (int i=0; i<N; i++) {
try {
mCallbacks.getBroadcastItem(i).valueChanged(value);
} catch (RemoteException e) {
// The RemoteCallbackList will take care of removing
// the dead object for us.
}
}
mCallbacks.finishBroadcast();
// Repeat every 1 second.
sendMessageDelayed(obtainMessage(REPORT_MSG), 1*1000);
} break;
default:
super.handleMessage(msg);
}
}
};
定义RemoteService的ServiceConnection.
/**
* 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 service object we can use to
// interact with the service. We are communicating with our
// service through an IDL interface, so get a client-side
// representation of that from the raw service object.
mService = IRemoteService.Stub.asInterface(service);
Log.v(TAG," onServiceConnected");
// We want to monitor the service for as long as we are
// connected to it.
try {
mService.registerCallback(mCallback);
} catch (RemoteException e) {
// In this case the service has crashed before we could even
// do anything with it; we can count on soon being
// disconnected (and then reconnected if it can be restarted)
// so there is no need to do anything here.
}
// As part of the sample, tell the user what happened.
}
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;
mKillButton.setEnabled(false);
mCallbackText.setText("Disconnected.");
// As part of the sample, tell the user what happened.
}
};
定义SecondaryService的ServiceConnection
/**
* Class for interacting with the secondary interface of the service.
*/
private ServiceConnection mSecondaryConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
// Connecting to a secondary interface is the same as any
// other interface.
Log.v(TAG,"mSecondaryConnection->onServiceConnected");
mSecondaryService = ISecondary.Stub.asInterface(service);
}
public void onServiceDisconnected(ComponentName className) {
mSecondaryService = null;
}
};
BindService:
Log.v(TAG,"mBindListener:onClick");
Log.v(TAG,"IRemoteService.class.getName = " + IRemoteService.class.getName());
boolean bResult = bindService(new Intent(IRemoteService.class.getName()),
mConnection, Context.BIND_AUTO_CREATE);
Log.v(TAG, " bResult = " + bResult );
bResult = bindService(new Intent(IRemoteService.class.getName()),
mConnection1, Context.BIND_AUTO_CREATE);
Log.v(TAG, " bResult = " + bResult );
bindService(new Intent(ISecondary.class.getName()),
mSecondaryConnection, Context.BIND_AUTO_CREATE);
mIsBound = true;
调用RemoteService:
if (mIsBound) {
// If we have received the service, and hence registered with
// it, then now is the time to unregister.
if (mSecondaryService!= null) {
try {
Log.v(TAG,"onClick");
mService.updateValue();
} catch (RemoteException e) {
// There is nothing special we need to do if the service
// has crashed.
}
}
}
调用SecondaryService:
if (mIsBound) {
// If we have received the service, and hence registered with
// it, then now is the time to unregister.
if (mService != null) {
try {
Log.v(TAG, " Pid = " + mSecondaryService.getPid());
} catch (RemoteException e) {
// There is nothing special we need to do if the service
// has crashed.
}
}
mCallbackText.setText("call remote service.");
}
unbindService
if (mIsBound) {
// If we have received the service, and hence registered with
// it, then now is the time to unregister.
if (mService != null) {
try {
mService.unregisterCallback(mCallback);
} catch (RemoteException e) {
// There is nothing special we need to do if the service
// has crashed.
}
}
// Detach our existing connection.
unbindService(mConnection);
unbindService(mSecondaryConnection);
mIsBound = false;