数据传送
客户端与服务端通信的状态图:
客户端服务端线程
在图中可以看到有两个线程: 1.
1. 一个是服务端的一个线程,这个线程负责源源不断的从HAL读取数据。 2. 另一个是客户端的一个线程,客户端线程负责从消息队列中读数据。
创建消息队列
客户端可以创建多个消息队列,一个消息队列对应有一个与服务器通信的连接接口 创建连接接口
服务端与客户端沟通的桥梁,服务端读取到HAL层数据后,会扫面有多少个与客户端连接的接口,然后往每个接口的管道中写数据
创建管道
每一个连接接口都有对应的一个管道。
上面是设计者设计数据传送的原理,但是目前Android4.1上面的数据传送不能完全按照上面的理解。
因为在实际使用中,消息队列只会创建一个,也就是说客户端与服务端之间的通信只有一个连接接口,只有一个管道传数据。
那么数据的形式是怎么从HAL层传到JAVA层的呢?
其实数据是以一个结构体sensors_event_t的形式从HAL层传到JNI层。看看HAL的sensors_event_t结构体:
typedef struct sensors_event_t { int32_t version;
int32_t sensor; //标识符 int32_t type; //传感器类型 int32_t reserved0;
int64_t timestamp; //时间戳 union {
float data[16];
sensors_vec_t acceleration; //加速度 sensors_vec_t magnetic; //磁矢量 sensors_vec_t orientation; //方向 sensors_vec_t gyro; //陀螺仪 float temperature; //温度 float distance; //距离 float light; //光照 float pressure; //压力
float relative_humidity; //相对湿度 };
uint32_t reserved1[4]; } sensors_event_t;
View Code
在JNI层有一个ASensorEvent结构体与sensors_event_t向对应,frameworks/native/include/android/sensor.h:
typedef struct ASensorEvent { int32_t version; int32_t sensor;
int32_t type; int32_t reserved0; int64_t timestamp; union { float data[16]; ASensorVector vector; ASensorVector acceleration; ASensorVector magnetic; float temperature; float distance; float light; float pressure; }; int32_t reserved1[4]; } ASensorEvent; View Code 交互调用时序图
经过前面的介绍,现在知道了客户端实现的方式及服务端的实现,但是没有具体讲到它们是如何进行通信的,现在看看客户端与服务端之间的通信。
主要涉及的是进程间通信,有IBind和管道通信。
客户端通过IBind通信获取到服务端的远程调用,然后通过管道进行sensor数据的传输。
服务端
native层实现了sensor服务的核心实现,Sensor服务的主要流程的实现在sensorservice类中,下面重点分析下这个类的流程。
class SensorService :
public BinderService
View Code
看看sensorService继承的类:
继承BinderService
template
public:
static status_t publish() {
sp
return sm->addService(String16(SERVICE::getServiceName()), new SERVICE());
}
static void publishAndJoinThreadPool() {
sp
sm->addService(String16(SERVICE::getServiceName()), new SERVICE());
ProcessState::self()->startThreadPool(); IPCThreadState::self()->joinThreadPool(); }
static void instantiate() { publish(); } };
}; // namespace android
View Code
在前面的介绍中,SensorService服务的实例是在System_init.cpp中调用
SensorService::instantiate()创建的,即调用了上面的instantiate()方法,接着调用了publish(),在该方法中,我们看到了new SensorService的实例,并且调用了defaultServiceManager::addService()将Sensor服务