当前位置:首页 > 嵌入式培训 > 嵌入式学习 > 讲师博文 > Sensor框架结构分析

Sensor框架结构分析 时间:2018-09-28      来源:未知

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的驱动。

上一篇:同步ubuntu粘贴板和windows系统粘贴板

下一篇:UI设计

热点文章推荐
华清学员就业榜单
高薪学员经验分享
热点新闻推荐
前台专线:010-82525158 企业培训洽谈专线:010-82525379 院校合作洽谈专线:010-82525379 Copyright © 2004-2022 北京华清远见科技集团有限公司 版权所有 ,京ICP备16055225号-5京公海网安备11010802025203号

回到顶部