在UI线程和Service线程中经常需要进行数据通信,而除了Bundles之外的另一种方法便为AIDL,Demo(Pedometer)步骤、逻辑及代码:
首先先编辑好两个.aidl文件:
IsStepService.aidl:
import
com.jwetherell.pedometer.service.IStepServiceCallback;
interface IStepService {
boolean isRunning();
void setSensitivity(int
sens);
void
registerCallback(IStepServiceCallback cb);
void
unregisterCallback(IStepServiceCallback cb);
}
IsStepServiceCallback.aidl:
interface IStepServiceCallback {
void stepsChanged(int value);
}
第二,实例化两个远程接口:
因为这个程序是一个客户端和一个服务端,而且是相互调用的关系,所以要在客户端中实现IStepServiceCallback:
private static final IStepServiceCallback.Stub mCallback = new
IStepServiceCallback.Stub() {
@Override
public IBinder asBinder() {
return mCallback;
}
@Override
public void stepsChanged(int value) throws RemoteException {
logger.info("Steps=" + value);
Message msg = handler.obtainMessage();
msg.arg1 = value;
handler.sendMessage(msg);
}
};
而在服务端中实现IStepService:
private final IStepService.Stub mBinder = new
IStepService.Stub() { @Override
public boolean isRunning() throws RemoteException {
return running;
}
@Override
public void setSensitivity(int sens) throws RemoteException {
logger.info("setSensitivity: " + sens);
StepDetector.setSensitivity(sens);
}
@Override
public void registerCallback(IStepServiceCallback cb) throws
RemoteException {
if (cb == null) return;
logger.info("registerCallback: " + cb.toString());
cb.stepsChanged(mSteps);
if (!mCallbacks.contains(cb)) mCallbacks.add(cb);
}
@Override
public void unregisterCallback(IStepServiceCallback cb) throws
RemoteException {
if (cb == null) return;
logger.info("unregisterCallback: " + cb.toString());
if (mCallbacks.contains(cb)) mCallbacks.remove(cb);
}
};
最后,就可以利用BindService以及实例化的aidl去实现通信了。
但是值得注意的是,在客户端实例化ServiceConnection并重载onServiceConnected(ComponentName
className, IBinder service)方法时,需要做以下两步:
mService =
IStepService.Stub.asInterface(service);
mService.registerCallback(mCallback);
step1利用aidl的asInterface方法增加一个IStepService实例,step2是将增加的实例注册回调,而且IStepService是在服务端定义的,mCallback则是客户端通过IStepServiceCallback.Stub实例化的。反过来看服务端的IBinder:
public IBinder onBind(Intent intent) {
return mBinder;
}
其中mBinder是IStepService.Stub实例化的,而且IStepService.Stub同样是在客户端定义的。这样,服务端就能调用客户端的方法。