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