如何从不同进程中的远程服务向IPC客户端发送数据
How to send data to an IPC client from a remote service in different processes
有一个IPC客户端和一个IPC服务器(远程服务)属于不同的进程。在客户端绑定到远程服务后,我需要开始向客户端连续发送数据。我可以绑定到服务并从客户端调用 AIDL 方法,但是我找不到方法将数据从远程服务发送到客户端。
这可以通过在 AIDL 中使用远程回调来实现。服务器实现了一个AIDL,它允许客户端在绑定到服务后注册一个远程回调(回调也是一个AIDL)。然后服务器可以在需要时调用远程回调向客户端发送数据。请参阅下面来自 Android API 演示的代码片段。
interface IRemoteService {
/**
* Often you want to allow a service to call back to its clients.
* This shows how to do so, by registering a callback interface with
* the service.
*/
void registerCallback(IRemoteServiceCallback cb);
/**
* Remove a previously registered callback interface.
*/
void unregisterCallback(IRemoteServiceCallback cb);
}
oneway interface IRemoteServiceCallback {
/**
* Called when the service has a new value for you.
*/
void valueChanged(int value);
}
客户端和服务器端代码都可以在RemoteService.java
看到
注册远程回调的客户端代码
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);
mKillButton.setEnabled(true);
mCallbackText.setText("Attached.");
// 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.
}
调用客户端远程回调的服务端代码
`// Broadcast to all clients the new value.
final int N = mCallbacks.beginBroadcast();
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();`
有一个IPC客户端和一个IPC服务器(远程服务)属于不同的进程。在客户端绑定到远程服务后,我需要开始向客户端连续发送数据。我可以绑定到服务并从客户端调用 AIDL 方法,但是我找不到方法将数据从远程服务发送到客户端。
这可以通过在 AIDL 中使用远程回调来实现。服务器实现了一个AIDL,它允许客户端在绑定到服务后注册一个远程回调(回调也是一个AIDL)。然后服务器可以在需要时调用远程回调向客户端发送数据。请参阅下面来自 Android API 演示的代码片段。
interface IRemoteService {
/**
* Often you want to allow a service to call back to its clients.
* This shows how to do so, by registering a callback interface with
* the service.
*/
void registerCallback(IRemoteServiceCallback cb);
/**
* Remove a previously registered callback interface.
*/
void unregisterCallback(IRemoteServiceCallback cb);
}
oneway interface IRemoteServiceCallback {
/**
* Called when the service has a new value for you.
*/
void valueChanged(int value);
}
客户端和服务器端代码都可以在RemoteService.java
看到注册远程回调的客户端代码
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);
mKillButton.setEnabled(true);
mCallbackText.setText("Attached.");
// 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.
}
调用客户端远程回调的服务端代码
`// Broadcast to all clients the new value.
final int N = mCallbacks.beginBroadcast();
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();`