android sensor 框架分析---客户端和服务端的连接
来源:互联网 发布:新东方游学数据 编辑:程序博客网 时间:2024/05/22 04:30
4,客户端和服务端的连接
在上一章初始化的过程中论述到, SensorManager.cpp会通过binder机制调用sensor服务的getSensorList方法获取sensor的相关信息。
那数据是通过binder机制调用服务端获取的吗?
其实, java层的SystemSensorManager.java和SensorManager.cpp是对应的;
java层的SensorEventQueue和SensorEventQueue.cpp是对应的;
4.1 连接流程分析
android_hardware_SensorManager.cpp中对应的nativeInitBaseEventQueue为nativeInitSensorEventQueue,主要逻辑如下,
1,调用SensorManager的createEventQueue方法,
SensorManager* mgr = reinterpret_cast<SensorManager*>(sensorManager);•••sp<SensorEventQueue> queue(mgr->createEventQueue(clientName, mode));
2,构造Receiver对象,
sp<Receiver> receiver = new Receiver(queue, messageQueue, eventQWeak, scratch);
createEventQueue方法之后的调用流程图如下,
SensorService.cpp的createSensorEventConnection逻辑如下,
1,首先在客户端和服务端之间构造一个连接,
sp<SensorEventConnection> result(new SensorEventConnection(this, uid, packageName, requestedMode == DATA_INJECTION, opPackageName));
2,将该连接加入到mActiveConnections变量中。
if (mActiveConnections.indexOf(result) < 0) { mActiveConnections.add(result); }
mActiveConnections中保存着服务端和不同客户端的连接对象。
一个android系统中虽然只有一个服务端,但是可以有很多不同的客户端,客户端以进程的uid和包名区分。
当然,对于同一种sensor,也可以同时有不同的客户端进行连接。
BitTube的init方法如下,
void BitTube::init(size_t rcvbuf, size_t sndbuf) { int sockets[2]; if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets) == 0) { size_t size = DEFAULT_SOCKET_BUFFER_SIZE; setsockopt(sockets[0], SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf)); setsockopt(sockets[1], SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf)); // sine we don't use the "return channel", we keep it small... setsockopt(sockets[0], SOL_SOCKET, SO_SNDBUF, &size, sizeof(size)); setsockopt(sockets[1], SOL_SOCKET, SO_RCVBUF, &size, sizeof(size)); fcntl(sockets[0], F_SETFL, O_NONBLOCK); fcntl(sockets[1], F_SETFL, O_NONBLOCK); mReceiveFd = sockets[0]; mSendFd = sockets[1]; } else { mReceiveFd = -errno; ALOGE("BitTube: pipe creation failed (%s)", strerror(-mReceiveFd)); }}
由此可见,服务端进程和客户端进程采用管道流的方式进行通信,并且是单向通信。
服务端的端口为mReceiveFd,只进行数据的发送,
客户端的端口为mSendFd,只进行数据的读取。
并且客户端还可以通过getFd方法来获取mSendFd进行读取数据。
4.2 nativeEnableSensor分析
android_hardware_SensorManager.cpp的nativeEnableSensor方法如下,
static jint nativeEnableSensor(JNIEnv *env, jclass clazz, jlong eventQ, jint handle, jint rate_us, jint maxBatchReportLatency) { sp<Receiver> receiver(reinterpret_cast<Receiver *>(eventQ)); return receiver->getSensorEventQueue()->enableSensor(handle, rate_us, maxBatchReportLatency, 0);}
内部类receiver和SensorEventQueue.cpp是在Java层构造SensorEventQueue对象是调用nativeInitBaseEventQueue方法
而在对应的JNI方法中完成初始化的。
调用流程图如下,
SensorEventQueue.cpp的enableSensor方法如下,
status_t SensorEventQueue::enableSensor(int32_t handle, int32_t samplingPeriodUs, int maxBatchReportLatencyUs, int reservedFlags) const { return mSensorEventConnection->enableDisable(handle, true, us2ns(samplingPeriodUs), us2ns(maxBatchReportLatencyUs), reservedFlags);}
mSensorEventConnection就是sensor服务端SensorEventConnection在客户端的一个代理, SensorEventConnection
是SensorService.cpp的内部类。
4.3 Receiver分析
前面2个步骤主要是为了获取sensor数据做准备工作,读取数据主要是android_hardware_SensorManager.cpp的内部类
Receiver继承于LooperCallback,
class Receiver : public LooperCallback {
onFirstRef方法会调用BitTube的getFd方法来获取mSendFd进行读取数据。
mMessageQueue->getLooper()->addFd(mSensorQueue->getFd(), 0, ALOOPER_EVENT_INPUT, this, mSensorQueue.get());
回调handleEvent方法首先会读取服务端写入的sensor数据,
while ((n = q->read(buffer, 16)) > 0) {
然后回调Java层的dispatchSensorEvent方法。
env->CallVoidMethod(receiverObj.get(),gBaseEventQueueClassInfo.dispatchSensorEvent, buffer[i].sensor, mScratch, status, buffer[i].timestamp);
- android sensor 框架分析---客户端和服务端的连接
- android sensor 框架分析---服务端
- android sensor 框架分析---客户端
- android sensor 框架分析---sensor数据流分析
- android sensor 框架分析---sensor native分析
- android sensor 框架分析---sensor 总结
- TCP服务端和客户端的框架
- web客户端,服务端,android客户端关于JSON的使用分析
- 简单的Android服务端和客户端登录交互(服务端)
- 客户端与服务端连接分析(一)
- 简单的Android服务端和客户端登录交互(客户端)
- Netty学习心得 netty服务端和客户端的连接
- android客户端通过json连接servlet服务端
- Android Sensor架构和原理分析
- 使用Mina框架开发 QQ Android 客户端(2) 客户端与服务端的通信
- zookeeper客户端和服务端交互分析
- Android 搭建客户端手机和服务端的交互
- Android手机 (客户端)和PCweb 端(服务端)的socket通信
- Juniper SRX----------远程管理实验
- 题目1462:两船载物问题
- IT生涯的第一篇
- Hive数据导入预处理-分隔符处理
- 比特币开发者指南--操作模式
- android sensor 框架分析---客户端和服务端的连接
- vi编辑器常用命令
- Arduino 串口读写 SD 卡模块
- 110. Balanced Binary Tree
- servlet基础知识3
- springmvc-学习总结-全局异常处理
- 第三步,下载刷机软件和刷机包。 1.miflash 小米官方刷机软件 http://bigota.d.miui.com/tools/MiPhone20151028.exe 2.下载刷机包。
- Java关键字和保留字
- Qt(C++)项目中使用 Basler 工业相机(1)