Hi,欢迎来到中国优发娱乐手机版高端品牌 - 华清远见嵌入式学院<北京总部官网>,专注嵌入式工程师培养13年!
  • 全国咨询热线:400-706-1880
  • 新浪微博
  • 微信
  • 北京
    校区
  • 上海
    校区
  • 深圳
    校区
  • 成都
    校区
  • 南京
    校区
  • 武汉
    校区
  • 西安
    校区
  • 广州
    校区
  • 沈阳
    校区
  • 济南
    校区
  • 重庆
    校区
  • 研发
    中心
  • 当前位置: > 嵌入式学院 > 嵌入式学习 > 讲师博文 > Sensor框架结构分析
    Sensor框架结构分析
    时间:2017-04-26作者:华清远见
    1.Sensor的概念 Sensor即传感器,在当前智能手机上大量存在:G-Sensor、LightsSensor、ProximitySensor、TemperatureSensor等,其作为Android系统的一个输入设备,对于重视用户体验的移动设备来说是必不可少的。Sensor虽然是一个输入设备,但是它又不同于触摸屏,键盘,按键等这些常规的输入设备,因为Sensor的数据输入从传感器硬件到设备的,而常规的输入设备是从用户到设备的,比如:温度传感器用于感知温度的变化,采样传感器数据上报给设备。而传感器硬件的工作与否,采样精度是由用户来控制的,所以对应Sensor而言是其工作方式是双向的,即:控制硬件的控制流,硬件上报的数据流。   2.Sensor的应用程序怎么写 【1】通过调用 Context.getSystemService(SENSOR_SERVICE)获得传感器服务,实现返回的是封装了SensorService的SensorManager对象 【2】调用SensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION)来获得指定类型的传感器对象,方便获得传感器的数据 【3】通过SensorManager.registerListener注册SensorEventListener监听器,监听获得的传感器对象,当传感器数据提交上来时,能被应用程序得到 3.SensorManager的获取 咱们已经写出来Sensor的应用程序,现在咱们来分析一下Sensor的app到低是怎么调用驱动来获得数据的。在写应用程序的时候首先获得一个SensorManager。调用的函数接口是getSystemService();先打开下面这个文件frameworks/base/core/java/android/app/ ContextImpl.java,咱们可以看到如下代码。     public Object getSystemService(String name) {         ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name);         return fetcher == null ? null : fetcher.getService(this); }   通过函数的第一句话我们可以看到它是按name来从SYSTEM_SERVICE_MAP中来获取一个ServiceFetcher类。在当前文件中我们可以查看到SYSTEM_SERVICE_MAP的定义如下。 private static final HashMap<String, ServiceFetcher> SYSTEM_SERVICE_MAP =             new HashMap<String, ServiceFetcher>(); 我们来看一下ServiceFetcher这个函数都干了什么事情。     /*package*/ static class ServiceFetcher {         int mContextCacheIndex = -1;           /**          * Main entrypoint; only override if you don't need caching.          */         public Object getService(ContextImpl ctx) {             ArrayList<Object> cache = ctx.mServiceCache;             Object service;             synchronized (cache) {                 if (cache.size() == 0) {                     // Initialize the cache vector on first access.                     // At this point sNextPerContextServiceCacheIndex                     // is the number of potential services that are                     // cached per-Context.                     for (int i = 0; i < sNextPerContextServiceCacheIndex; i++) {                         cache.add(null);                     }                 } else {                     service = cache.get(mContextCacheIndex);                     if (service != null) {                         return service;                     }                 }                 service = createService(ctx);                 cache.set(mContextCacheIndex, service);                 return service;             }         }           /**          * Override this to create a new per-Context instance of the          * service.  getService() will handle locking and caching.          */         public Object createService(ContextImpl ctx) {             throw new RuntimeException("Not implemented");         }     } 接着我们看到return时,函数调用了fetcher.getService(this)这个方法。 通过这段代码我们知道,cache里面没有这个服务时就会通过cache.add来添加一个服务。如果已经注册过了执行cache.get()来获得服务。最终这个函数返回的都是一个service。你可能很困惑不是要得到Manager吗?怎么返回的是一个service?   我们能够清楚的知道Manager是Service的父类。我们知道我们的注册的服务存放在ArrayList<Object> cache = ctx.mServiceCache;里面。咱们可以在registerService(String serviceName, ServiceFetcher fetcher)中查看到我们注册的Sensor服务         registerService(SENSOR_SERVICE, new ServiceFetcher() {                 public Object createService(ContextImpl ctx) {                     return new SystemSensorManager(ctx.getOuterContext(),                       ctx.mMainThread.getHandler().getLooper());                 }}); 看到这个函数中有Handler和looper,这两个又是用来干什么的那?我们在学Android应用层的时候知道,普通线程想在activity直接显示内容是不可能的,用户线程要把显示的内容发送到消息队列中,然后调用looper.Loop来循环调用消息队列,主线程通过handler来从消息队列中获取消息。   总结一下: 用户程序调用getSystemService(SENSOR_SERVICE),其实现在ContextImpl.java中,在其中实现从SYSTEM_SERVICE_MAP键值表查找与SENSOR_SERVICE键对应的对象ServiceFetcher,调用ServiceFetcher.getService方法得到SensorManager对象,而ContextImpl对象里还维护着一个ServiceCache,如果某个服务被get过一次,就会被记录在这个所谓缓存里,ServiceFetcher.getService先查找缓存里有没有Cache的Object,如果没有,则调用自己的createService方法创建这个Object,而createService没有实现,其在registerService注册服务时创建ServiceFetcher匿名内部类时实现,并且将注册的服务添加到SYSTEM_SERVICE_MAP中,在创建SensorManager对象时,它和Activity共享了一个Looper。   4.SensorManager代码分析 我们先找到frameworks/base/core/java/android/hardware/SensorManager.java这个文件找到public abstract class SensorManager {}这个Java工程的类。我们仔细查看这个类中并没有什么实质性的代码,耐心查找下你会找到下面这个文件 frameworks/base/core/java/android/hardware/SystemSensorManager.java我们能看到下面这个类public class SystemSensorManager extends SensorManager {}它继承了Sensor的类 public SystemSensorManager(Context context, Looper mainLooper) {         mMainLooper = mainLooper;         mTargetSdkLevel = context.getApplicationInfo().targetSdkVersion;         synchronized(sSensorModuleLock) {             if (!sSensorModuleInitialized) {                 sSensorModuleInitialized = true;                   nativeClassInit();                   // initialize the sensor list                 final ArrayList<Sensor> fullList = sFullSensorsList;                 int i = 0;                 do {                     Sensor sensor = new Sensor();                     i = nativeGetNextSensor(sensor, i);                     if (i>=0) {                         //Log.d(TAG, "found sensor: " + sensor.getName() +                         //        ", handle=" + sensor.getHandle());                         fullList.add(sensor);                         sHandleToSensor.append(sensor.getHandle(), sensor);                     }                 } while (i>0);             }         } 首先我们看到了mMainLooper = mainLooper;这个looper我们前面获得的。接着我们会看到两个重要的函数nativeClassInit();和nativeGetNextSensor(sensor, i);这两个函数见名知意,在nativeClassInit中通过GetFieldID来获得变量,最终被这些java变量通过jni存放到sensorOffsets这个结构体中。   static void  nativeClassInit (JNIEnv *_env, jclass _this) {     jclass sensorClass = _env->FindClass("android/hardware/Sensor");     SensorOffsets& sensorOffsets = gSensorOffsets;     sensorOffsets.name        = _env->GetFieldID(sensorClass, "mName",      "Ljava/lang/String;");     sensorOffsets.vendor      = _env->GetFieldID(sensorClass, "mVendor",    "Ljava/lang/String;");     sensorOffsets.version     = _env->GetFieldID(sensorClass, "mVersion",   "I");     sensorOffsets.handle      = _env->GetFieldID(sensorClass, "mHandle",    "I");     sensorOffsets.type        = _env->GetFieldID(sensorClass, "mType",      "I");    。。。。。。 }   nativeGetNextSensor里面是由c++语言来实现的。从第一句话中 SensorManager& mgr(SensorManager::getInstance());能够看得出来他创建了一个本地的SensorManager类,这与我们在应用层看到了是两个完全不同的类。   static jint nativeGetNextSensor(JNIEnv *env, jclass clazz, jobject sensor, jint next) {     SensorManager& mgr(SensorManager::getInstance());       Sensor const* const* sensorList;     size_t count = mgr.getSensorList(&sensorList);     if (size_t(next) >= count)         return -1;       Sensor const* const list = sensorList[next];     const SensorOffsets& sensorOffsets(gSensorOffsets);     jstring name = env->NewStringUTF(list->getName().string());     jstring vendor = env->NewStringUTF(list->getVendor().string());     jstring stringType = env->NewStringUTF(list->getStringType().string());     jstring requiredPermission = env->NewStringUTF(list->getRequiredPermission().string());     env->SetObjectField(sensor, sensorOffsets.name,      name);     env->SetFloatField(sensor, sensorOffsets.resolution, list->getResolution());     。。。。。。      next++;     return size_t(next) < count ? next : 0; }   我们来看下c++代码中的SensorManager是干嘛的,这里面只有一个assertStateLocked();我们来具体的分析一下。 SensorManager::SensorManager(): mSensorList(0) {assertStateLocked();} status_t SensorManager::assertStateLocked() const {     if (mSensorServer == NULL) {         // try for one second         const String16 name("sensorservice");         for (int i=0 ; i<4 ; i++) {             status_t err = getService(name, &mSensorServer);             if (err == NAME_NOT_FOUND) {                 usleep(250000);                 continue;             }             if (err != NO_ERROR) {                 return err;             }             break;         }         class DeathObserver : public IBinder::DeathRecipient {             SensorManager& mSensorManger;             virtual void binderDied(const wp<IBinder>& who) {                 ALOGW("sensorservice died [%p]", who.unsafe_get());                 mSensorManger.sensorManagerDied();             }         public:             DeathObserver(SensorManager& mgr) : mSensorManger(mgr) { }         };      //SensorManager和sensorService同生死           mDeathObserver = new DeathObserver(*const_cast<SensorManager *>(this));         mSensorServer->asBinder()->linkToDeath(mDeathObserver);           mSensors = mSensorServer->getSensorList();         size_t count = mSensors.size();         mSensorList = (Sensor const**)malloc(count * sizeof(Sensor*));         for (size_t i=0 ; i<count ; i++) {             mSensorList[i] = mSensors.array() + i;         }     }     return NO_ERROR; } 通过本源码的阅读你会清楚的知道这段代码主要是为了获得SensorService。那么我们不妨直接搜索一下SensorService.cpp void SensorService::onFirstRef() {     ALOGD("nuSensorService starting...");       SensorDevice& dev(SensorDevice::getInstance());       if (dev.initCheck() == NO_ERROR) {         sensor_t const* list;         ssize_t count = dev.getSensorList(&list);         if (count > 0) {             ssize_t orientationIndex = -1;             bool hasGyro = false;             uint32_t virtualSensorsNeeds =                     (1<<SENSOR_TYPE_GRAVITY) |                     (1<<SENSOR_TYPE_LINEAR_ACCELERATION) |                     (1<<SENSOR_TYPE_ROTATION_VECTOR);               mLastEventSeen.setCapacity(count);             for (ssize_t i=0 ; i<count ; i++) {                 registerSensor( new HardwareSensor(list[i]) );                 switch (list[i].type) {                     case SENSOR_TYPE_ORIENTATION:                         orientationIndex = i;                         break;                 }             } 通过这一句还我们能够看出SensorDevice& dev(SensorDevice::getInstance());它创建了SensorDevice,在SensorDevice中我们看到了hw_get_module();看到这个之后你应该会感觉到很开心了。    5.Sensor调用驱动过程 a. 在ContextImpl.java中注册SensorManager这个类 b. 在SensorManager.java中调用nativeClassInit()来初始化本地方法。 c. 在android_hardware_SensorManager.cpp这个函数中完成jni的调用 d. 在SensorManager.cpp中定义本地的SensorManager的类。 e. 在SensorService.cpp注册服务,向上层提供服务,下层调用SensorDevice。 f. 在SensorDevice.cpp中调用hw_get_module来调用Sensor的驱动。

    发表评论
    全国咨询电话:400-706-1880,双休日及节假日请致电值班手机:15010390966 在线咨询: 曹老师QQ(619366077), 余老师QQ(2657985593), 李老师QQ(2814652411), 徐老师QQ(1462495461) 企业培训洽谈专线:010-82600901,院校合作洽谈专线:010-82600350,在线咨询:QQ(248856300) Copyright 2004-2017 华清远见教育集团 版权所有 ,沪ICP备10038863号,京公海网安备110108001117号

    优发娱乐手机版

    百度360搜索搜狗搜索

    优发娱乐手机版

    百度360搜索搜狗搜索