这一期我们来分析一下Android中的SensorManager,那我们首先来看一下,这个SensorManager是在什么时候注册到我们的系统中的。这个SensorManager并不是使用ServiceManager来管理的,而是使用安卓自己的一套机制来管理的,那么我们来看一下SensorManager的注册情况
首先我们知道一个应用里面都会有一个context,而这个上下文就会被我们的contextIml这个模板来继承,然后还会被contextwrapper来继承,而我们这些继承关系到最后都会被Activity给继承,我们每一个应用都是一个Activity,这样我们的Activity就能从上到下获取到我们的context,而这个contextwrapper会有一个自己的成员,这个成员就是我们的context,而context指向的是contextIml模板,而这个模板在初始化的时候会注册所有的service,这些service并不是我们servicemanager管理的,而是他自己的一套机制,把所有的service映射到自己的映射表里,这样我们在应用中如果使用getservice,就可以直接在映射表中根据名字来拿到service。因为我们的SensorManager只是一个管理,并不是Sensorservice,我们真正的Sensorservice是在我们systemservice启动的时候启动的,然后在后面会把我们的Sensorservice给加到servicemanager中,这就是一个应用能拿到我们所有服务的一个情况,他并不是直接调用我们的servicemanager。
下面我们来看一下contextIml的一个具体实现,打开frameworks/base/core/java/android/app/ContextImpl.java,在这里他会把我们所有的服务基本上全部都列举了出来,我们来看一下这个ReceiverRestrictedContext类的具体实现
我们应用中的context其实就是这个类的一个实例,这个类就是注册我们系统中的所有服务,除了这些服务还有registerReceiver,然后还有registerReceiverAsUser,以及registerService,我们来看一下registerService的具体实现
他的实现就是传了一个service的名字,然后传进来一个ServiceFetcher,ServiceFetcher这个类就是我们自己创建的服务,我们把这些服务添加到SYSTEM_SERVICE_MAP哈希表中,我们添加一个服务,他就会使用哈希表的put方法,把我们的名字和fetcher添加到SYSTEM_SERVICE_MAP中。添加完之后我们来看一下如何调用
他调用的是getSystemService,调用的参数就是我们的name,比如我们想直接拿到SensorManager,那么直接调用getSystemService,名字就是SensorManager,这样我们就能拿到这个表中的服务。而我们真正的服务其实还要继续往下走调用我们的service的,而有些service是直接拿到我们SystemManager中的服务
下面我们来看一下SensorManager在framework层的一个大概框架图
其中SensorManager是我们的基类,他被我们的SystemSensorManager所继承,我们所注册的SensorManager的服务其实就是SystemSensorManager,具体的实现也就是在这个类中实现的而我们另一个重要的类就是我们的SensorManager(cpp)这个manager是我们的c++层的,它主要是负责和我们的Sensorservice进行交互,他进行交互的方式就是通过ServiceManager来获取SensorService,然后调用一些接口拿到我们系统真正传感器的一些操作。比如说我们拿到我们的getSensorList,这样我们就可以通过Bender机制,将Sensorservice中所探测到的我们传感器的所有类型的列表全部拿到,全部拿到之后就会将列表通过JNI传给我们的SensorManager,这样SensorManager就能拿到系统中所有的Sensor的类型和名字。那么我们在使用应用程序来调用SensorManager获取整个系统中Sensor数据和类型的时候,就不用每次都去get一次,因为Sensor注册号以后基本不会变的。
那么我们来看一下整个初始化的过程:首先是SystemSensorManager()进行初始化的时候,会调用nativeClassInit(),它主要是做一些偏移的工作,第二个会调用我们的native方法,也就是nativeGetNextSensor(),这个方法就是一次一次的调用我们SensorManager中的方法,去拿到我们Sensorserver中Sensor的类型,然后把它添加到我们本地的一个成员变量中,这个成员变量就会将我们的Sensor保存起来,我们的应用想要获取一个Sensor的话,直接调用就可以了,这样就不需要再次去访问底层的一些东西了。但是我们需要registerListener去监听一个Sensor数据的话,这时我们就需要做一个操作,要建立一个通道,这个通道就是从SensorManager到我们的JNI层,到我们的SensorManager(cpp),一直到我们的SensorServer,建立一个数据通道。这个通道就会将我们的SensorServer收到的底层的变化的值,向上一直传递给我们的SensorManager,而我们的SensorManager就会通过registerListener所调用的回调函数返回给我们的APP,这样我们的应用程序就能够获取我们Sensor的数据。他的大概流程就是这样的,下面我们在来看一下SensorManager的一个具体实现,以及SensorManager(cpp)是如何和我们sensorserver来建立关系的
我们首先来看一下SystemSensorManager,他所在的目录为:frameworks/base/core/java/android/hardware/SystemSensorManager.java 我们来看一下它的定义,它继承了我们的SensorManager,我们再来看一下SensorManager,这是我们的基类
他在初始化的时候会做两件事情,第一就是nativeClassInit(),现在我们来看一下这个native方法,它是在frameworks/base/core/jni/android_hardware_SensorManager.cpp中,他在这里其实就是做了一些偏移量的设置,我们来看一个比较重要的方法nativeGetNextSensor
在这里首先会定义一个fullList,他就是用来保存我们SensorList的,所有的Sensor都会添加到这个列表中,首先我们会new一个Sensor出来,然后使用这个nativeGetNextSensor方法去拿到我们的Sensor,我们来看一下它的具体实现:
在我们调用nativeGetNextSensor的时候,我们首先会实例化我们一个SensorManager,而他就是我们c++层的SensorManager,拿到我们的SensorManager就会去获取我们的SensorList,这个count的意思就是通过上边传过来的值,然后返回SensorList中的一个Sensor,我们会在这里将SensorList获取下来,获取之后会对Sensor的每一个变量进行操作,之后就会返回我们的值,然后把sensor的值添加到我们所传进来的变量中,这样我们就完成了一个Sensor的添加工作。我们来看一下getSensorList,首先这边有一个SensorManager,我们先来看一下,他在实例化的时候会调用assertStateLocked(),我们来看一下他的实现
如果说这个mSensorManager是NULL的话,那么他会去试着获取我们的Sensorservice,这个Sensorservice就是我们所在systemservice初始化的时候创建的,然后会得到我们的Sensorservice,拿到之后我们这端SensorManager就和我们的Sensorservice建立起联系来了,然后会调用gerSensorList的方法去拿到我们的SensorList,当初始化完成之后,如果我们有应用想要使用Sensor,他首先会获取Sensor的一个类型,然后使用registerListener的方法,去监听我们一个Sensor,这样我们来看一下整个过程是如何来进行的,我们将下边的内容放到下一期再来进行讲解。