C++中的JNI
相关文件:/frameworks/base/core/jni/android_hardware_SensorManager.cpp;
Java和C++的函数对应关系
本层及以下的所有相关代码都是为了实现这几个函数。
static JNINativeMethod gMethods[] = { {"nativeClassInit", "()V", (void*)nativeClassInit }, {"sensors_module_init","()I", (void*)sensors_module_init }, {"sensors_module_get_next_sensor","(Landroid/hardware/Sensor;I)I", (void*)sensors_module_get_next_sensor }, {"sensors_create_queue", "()I", (void*)sensors_create_queue }, {"sensors_destroy_queue", "(I)V", (void*)sensors_destroy_queue }, {"sensors_enable_sensor", "(ILjava/lang/String;II)Z", (void*)sensors_enable_sensor }, {"sensors_data_poll", "(I[F[I[J)I", (void*)sensors_data_poll }, };
nativeClassInit很简单,就是为了初始化gSensorOffsets。
sensors_module_init()模块初始化-->hw_get_module()-->load(),其实就是把sensor.so的链接库加载进来;
sensor.so是与机器相关的hardware层来实现的,要在hardware下实现相应的sensor.cpp;这个文件就是跟kernel打交道的最底层的文件了。里面主要完成了打开设备文件,读取设备节点的数据。比如我们的Gsensor是走的输入输出子系统,就打开相应的event文件来读取驱动上报的坐标数据。ANDROID_SINGLETON_STATIC_INSTANCE(SensorManager)
static jint sensors_module_init(JNIEnv *env, jclass clazz) { SensorManager::getInstance(); return 0; }估计你怎么也找不到SensorManager::getInstance,但是在SensorManager.cpp里你能找的这么一句:ANDROID_SINGLETON_STATIC_INSTANCE(SensorManager),ANDROID_SINGLETON_STATIC_INSTANCE是一个宏,定义在Singleton.h文件中。
#define ANDROID_SINGLETON_STATIC_INSTANCE(TYPE) \ template class Singleton< TYPE >; \ template<> Mutex Singleton< TYPE >::sLock(Mutex::PRIVATE); \ template<> TYPE* Singleton< TYPE >::sInstance(0);
Singleton是一个模板类,定义也在Singleton.h中
template <typename TYPE> class Singleton { public: static TYPE& getInstance() { Mutex::Autolock _l(sLock); TYPE* instance = sInstance; if (instance == 0) { instance = new TYPE(); sInstance = instance; } return *instance; } protected: ~Singleton() { }; Singleton() { }; private: Singleton(const Singleton&); Singleton& operator = (const Singleton&); static Mutex sLock; static TYPE* sInstance; };
这又是一个典型的单例模式获得类的对象,但是要注意这儿的SensorManager是本地的类,而不是Java层的SensorManager类。其实就是看看有没有初始化SensorManager类,没有的话new一个出来。下面我们就看一下SensorManager的构造函数。
SensorManager::SensorManager() : mSensorList(0) { const String16 name("sensorservice"); while (getService(name, &mSensorServer) != NO_ERROR) { usleep(250000); } 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; } }