一、AIDL接口定义
1、Server端aidl主接口(用于存放供给client端调用的方法)
interface ISetupMenuConfig {
void registerSetupNotification(in IDataChangeListener listener);
void unRegisterSetupNotification(in IDataChangeListener listener);
}
2、Server端aidl回调接口(用于存放要回调client端的方法)
interface IDataChangeListener {
void onChange(String nodeData);
}
二、建立服务端
要实现回调,需要新建RemoteCallbackList对象(一个存储回调对象的列表),通过类似发送广播的形式来实现回调
//通过import调用aidl接口
import com.xxx.xx.xxxx.xxxxx.ISetupMenuConfig;
import com.xxx.xx.xxxx.xxxxx.IDataChangeListener;
public class SetupMenuService extends Service {
private static final String TAG = "SetupMenuService";
public Context mContext;
private static RemoteCallbackList<IDataChangeListener> mRemoteCallbackList = null;
@Override
public void onCreate() {
super.onCreate();
mContext = this;
}
@Override
public IBinder onBind(Intent intent) {
mRemoteCallbackList = new RemoteCallbackList<IDataChangeListener>();
return mBinder;
}
private final ISetupMenuConfig.Stub mBinder = new ISetupMenuConfig.Stub() {
@Override
public void registerSetupNotification(IDataChangeListener listener) throws RemoteException {
Log.i(TAG, "registerSetupNotification != null");
if(listener != null){
mRemoteCallbackList.register(listener);
}
}
@Override
public void unRegisterSetupNotification(IDataChangeListener listener) throws RemoteException {
if(listener != null){
mRemoteCallbackList.unregister(listener);
}
}
};
public static void callback2Client(String nodeData) {
if (mRemoteCallbackList == null || mRemoteCallbackList.getRegisteredCallbackCount() <= 0) {return;}
synchronized (mRemoteCallbackList) {
//开始回调
mRemoteCallbackList.beginBroadcast();
int N = mRemoteCallbackList.getRegisteredCallbackCount();
Log.i(TAG,"callback2Client N ==" + N);
for (int i = 0; i < N; i++) {
try {
if (mRemoteCallbackList.getBroadcastItem(i) == null) {
continue;
}
Log.i(TAG,"callback2Client nodeData ==" + nodeData);
//get出来以后调用dataCalback到客户端去
mRemoteCallbackList.getBroadcastItem(i).onChange(nodeData);
} catch (DeadObjectException e) {
if (mRemoteCallbackList.getBroadcastItem(i) != null)
mRemoteCallbackList.unregister(mRemoteCallbackList.getBroadcastItem(i));
} catch (RemoteException e) {
e.printStackTrace();
}
}
//结束回调
mRemoteCallbackList.finishBroadcast();
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
}
}
三、建立客户端
使用aidl,实现回调方法
public class MainActivity extends Activity {
private static final String TAG = "MainActivity";
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main_activity);
Bundle args = new Bundle();
Intent intent = new Intent("com.xxx.xxxx.ISetupMenuService");
intent.putExtras(args);
startService(intent);
}
ISetupMenuConfig mService;
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
mService = ISetupMenuConfig.Stub.asInterface(service);
try {
mService.registerCallback(mCallback);
} catch (RemoteException e) {
}
}
public void onServiceDisconnected(ComponentName className) {
mService = null;
}
};
//供Server回调
private IDataChangeListener mCallback = new IDataChangeListener.Stub() {
public void onChange(String nodeData) {
printf("callback nodeData= " + nodeData);
}
};
}
总结下IPC的调用步骤:
- 声明一个接口类型的变量,该接口类型在.aidl文件中定义。
- 实现ServiceConnection。
- 调用bindService(),并在ServiceConnection实现中进行传递.在ServiceConnection.onServiceConnected()实现中,会接收一个IBinder实例(被调用的Service). 调用 xxxxx.Stub.asInterface((IBinder)service)将参数转换为xxxxxx类型。
- 调用接口中定义的方法。
- 断开连接,调用unbindService()