最近工作中在开发beacon的模块,里面涉及到beacon扫描的问题,然后就决定将beacon的扫描模块单独开发成一个SDK,单独放到一个进程里面,下面说一下开发中遇到的各种坑:
1、AIDL的问题;
2、RemoteCallbackList 对于activity的回调问题;
下面一步步的进行说明:
AIDL
AIDL的设计主要是进行跨进程的通信,其底层的实现是使用binder机制,其机制后续再讲解;在使用aidl的时候需要注意几点:aidl文件、parcelable的参数、in out inout 关键字的含义、service绑定的时候serviceconnection的连接:下面一个个进行讲解;
首先就是aidl文件定义的是一个接口,他的全称是Android Interface Definition Language,声明比较简单。需要关注的就是接口里面参数问题,参数类型必须是基本类型或者parcelable的复杂类型,list只是支持arraylist,map也是只支持hashmap,下面看一个例子:
packagecom.mm.beacon;
importcom.mm.beacon.IBeacon;
// Declare any non-default types here with import statements
interfaceIBeaconDetect {
voidonBeaconDetect(inListlist);
}
还有一个地方就是引用外部的复杂对象,也还是需要顶一个aidl的文件进行应用如下:
packagecom.mm.beacon;
parcelable IBeacon;
否则的话在引用的时候可能就会出现找不到相关的类;
in、out:
in:客户端的参数输入;
解析:是把实参的值赋值给行参 那么对行参的修改,不会影响实参的值
out:服务端的参数输入;
解析:传递以后,行参和实参都是同一个对象,只是他们名字不同而已,对行参的修改将影响实参的值
inout:这个可以叫输入输出参数,客户端可输入、服务端也可输入。客户端输入了参数到服务端后,服务端也可对该参数进行修改等,最后在客户端上得到的是服务端输出的参数。
因此在使用基本类型进行参数传递的时候,都是使用 in;
RemoteCallbackList
使用RemoteCallbackList目的进行remote service的回调下面看一下具体的使用方法:
首先就是需要声明一个回调的aidl,代码如下:
IRemoteInterface.aidl
interface IRemoteInterface {
void registerCallback(IBeaconDetect cb);
void unregisterCallback(IBeaconDetect cb);
}
下面看一下IBeaconDetect的声明:
IRemoteInterface.aidl
interface IBeaconDetect {
void onBeaconDetect(in List list);
void onRawDataDetect(in List list);
}
private final RemoteCallbackList mCallbacks = new RemoteCallbackList();
private IRemoteInterface.Stub mLocalBinder = new IRemoteInterface.Stub() {
@Override
public void registerCallback(IBeaconDetect cb) throws RemoteException {
mCallbacks.register(cb);
}
@Override
public void unregisterCallback(IBeaconDetect cb) throws RemoteException {
mCallbacks.unregister(cb);
}
};
在onBinder的时候返回的就是那个mLocalBinder. 在serviceConnecttion的时候注册的代码如下:
private IRemoteInterface.Stub mLocalBinder = new IRemoteInterface.Stub() {
@Override
public void registerCallback(IBeaconDetect cb) throws RemoteException {
mCallbacks.register(cb);
}
@Override
public void unregisterCallback(IBeaconDetect cb) throws RemoteException {
mCallbacks.unregister(cb);
}
};
private IBeaconDetect.Stub mCallback = new IBeaconDetect.Stub() {
@Override
public void onBeaconDetect(List beaconlist) throws RemoteException {
Log.e("callback",beaconlist.size()+"");
.......
}
@Override
public void onRawDataDetect(List list){
Log.e("onRawDataDetect",list.size()+"");
}
};
上面就是使用RemoteCallbackList进行回调的过程。
下章将会详细讲一个aidl的原理
网友评论