




已閱讀5頁,還剩19頁未讀, 繼續(xù)免費閱讀
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
android有關(guān)sensor的源碼總結(jié) 雖然這篇文章寫得很差,因為趕時間,所以就匆匆忙忙地寫出來自己作一個筆記。但是我想對大家應(yīng)該有一點幫助。 1、有關(guān)sensor在Java應(yīng)用程序的編程(以注冊多個傳感器為例,這程序是我臨時弄出來的,可能有錯)package com.sensors.acc;import android.app.Activity;import android.os.Bundle;import android.util.Log;import android.widget.TextView;import android.hardware.SensorManager;import android.hardware.Sensor;import android.hardware.SensorEvent;import android.hardware.SensorEventListener;public class acc extends Activity float x, y, z; SensorManager sensormanager = null; Sensor accSensor = null; Sensor lightSensor = null; Sensor proximitySensor = null; TextView accTextView = null; /* Called when the activity is first created. */ Override public void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState); setContentView(R.layout.main); sensormanager = (SensorManager)getSystemService(SENSOR_SERVICE); accSensor = sensormanager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); lightSensor = sensormanager.getDefaultSensor(Sensor.TYPE_LIGHT); proximitySensor = sensormanager.getDefaultSensor(Sensor.TYPE_PROXIMITY); accTextView = (TextView)findViewById(R.id.textview_name); SensorEventListener lsn = new SensorEventListener() public void onSensorChanged(SensorEvent e) if (e.sensor = accSensor) Log.d(sensor, found acc sensor); x = e.valuesSensorManager.DATA_X; y = e.valuesSensorManager.DATA_Y; z = e.valuesSensorManager.DATA_Z; accTextView.setText(x = + x + , ny = + y + , nz = + z); else if (e.sensor = lightSensor) Log.d(sensor, found light sensor); accTextView.setText(data is + e.values0); else if (e.sensor = proximitySensor) Log.d(sensor, found proximity sensor); accTextView.setText(distance is + e.values0); public void onAccuracyChanged(Sensor s, int accuracy) ; Override protected void onResume() super.onResume(); / register this class as a listener for the orientation and accelerometer sensors sensormanager.registerListener(lsn, accSensor, SensorManager.SENSOR_DELAY_NORMAL); sensormanager.registerListener(lsn, lightSensor, SensorManager.SENSOR_DELAY_NORMAL); sensormanager.registerListener(lsn, proximitySensor, SensorManager.SENSOR_DELAY_NORMAL);/ sensormanager.unregisterListener(lsn); Override protected void onStop() / unregister listener sensormanager.unregisterListener(lsn, accSensor); sensormanager.unregisterListener(lsn, lightSensor);sensormanager.unregisterListener(lsn, proximitySensor); super.onStop(); 在onCreate()函數(shù)中,調(diào)用getSystemService(SENSOR_SERVICE)初始化一個SensorManager實例,為什么要用getSystemService函數(shù),而不直接用new SensorManager呢?我們看此函數(shù)的實現(xiàn),在ApplicationContext.java中,if (SENSOR_SERVICE.equals(name) return getSensorManager();然后getSensorManager()的實現(xiàn) private SensorManager getSensorManager() synchronized (mSync) if (mSensorManager = null) mSensorManager = new SensorManager(mMainThread.getHandler().getLooper(); return mSensorManager;看到?jīng)]有?初始化SensorManager的時候需要mMainThread.getHandler().getLooper()這個參數(shù),之個應(yīng)該是用來傳遞消息用的,在SensorManager類的構(gòu)造函數(shù)中會把此參數(shù)傳給類成員mMainLooper。如果用new SensorManager()就需要另外獲取mainLooper參數(shù)傳遞進去。2、在android中跟sensor有關(guān)的一些文件有SensorManager.java,位于frameworksbasecorejavaandroidhardware目錄下,SensorService.java,位于frameworksbaseservicesjavacomandroidserver目錄下,android_hardware_SensorManager.cpp,位于frameworksbasecorejni目錄下,與SensorManager.java相對應(yīng),com_android_server_SensorService.cpp,在frameworksbaseservicesjni目錄下,與SensorService.java相對應(yīng)。還有SystemServer.java文件,HardwareLibhardwareIncludeHardware目錄下的Sensor.h頭文件。另外我們需要根據(jù)Sensor.h實現(xiàn)自己的一個源文件,一般取名為sensors_xxx.c或者sensors_xxx.cpp。3、SensorManager類分析有幾個函數(shù)比較重要,必須清晰理解它們的實現(xiàn),才能了解整個傳感器系統(tǒng)的實現(xiàn)。從而更好地去實現(xiàn)硬件抽象層的實現(xiàn)。幾個比較重要的函數(shù)有構(gòu)造函數(shù)SensorManager(), registerListener()和unregisterListener(),其中registerListener()和unregisterListener()有多個,標志為 Deprecated的是過時的,就不要看了。(1)構(gòu)造函數(shù)SensorManager(Looper mainLooper)這個函數(shù)首先獲取得傳感器系統(tǒng)服務(wù),并賦給類成員mSensorService, mSensorService = ISensorService.Stub.asInterface( ServiceManager.getService(Context.SENSOR_SERVICE);這里我要說一句,就是關(guān)于這個傳感器系統(tǒng)服務(wù),很多書上都說用getSystemService()是獲得傳感器的系統(tǒng)服務(wù),而它返回的是SensorManager類型,所以以為整個系統(tǒng)都是使用同一個SensorManager類的實例,以為我們在任何地方使用的SensorManager實例都是同一個,它們的公共成員是共享的。但是經(jīng)過這兩天的分析,這種說法是錯誤的。其實每次調(diào)用getSystemService()函數(shù)時都初始化一個新的SensorManager實例,而這個SensorManager實例會在構(gòu)造函數(shù)里通過取得傳感器系統(tǒng)服務(wù)SensorService來實現(xiàn)對下層傳感器的一些控制。而這個SensorService才是系統(tǒng)的傳感器服務(wù),說服務(wù),不如說它只是SensorService類的一個實例罷了。它只在系統(tǒng)初始化時初始化一次。Android中的系統(tǒng)服務(wù)機制應(yīng)該跟傳感器的都差不多一個樣,都是由不同的Manager調(diào)用下層相同的Service。你可以列舉其它的Manager。那它是什么時候初始化呢?它是系統(tǒng)初始化在SystemServer進程里創(chuàng)建的,SystemServer是一個管理很多系統(tǒng)服務(wù)的進程,我們轉(zhuǎn)到SystemServer.的main函數(shù)里,可以看到一直到調(diào)用int2()函數(shù),它會創(chuàng)建一個ServerThread,最終調(diào)用AdbSettingsObserver類的run()函數(shù),在run()函數(shù)里有這么有一句 / Sensor Service is needed by Window Manager, so this goes first Log.i(TAG, Sensor Service); ServiceManager.addService(Context.SENSOR_SERVICE, new SensorService(context);這里就創(chuàng)建SensorService實例了。在創(chuàng)建這個實例時會在SensorService構(gòu)造函數(shù)中調(diào)用jni函數(shù) public SensorService(Context context) if (localLOGV) Log.d(TAG, SensorService startup); _sensors_control_init(); 我們看_sensors_control_init();對應(yīng)的為static jintandroid_init(JNIEnv *env, jclass clazz) sensors_module_t* module; if (hw_get_module(SENSORS_HARDWARE_MODULE_ID, (const hw_module_t*)&module) = 0) if (sensors_control_open(&module-common, &sSensorDevice) = 0) const struct sensor_t* list; int count = module-get_sensors_list(module, &list); return count; return 0;它主要調(diào)用了sensor.h中的sensors_control_open()static inline int sensors_control_open(const struct hw_module_t* module, struct sensors_control_device_t* device) return module-methods-open(module, SENSORS_HARDWARE_CONTROL, (struct hw_device_t*)device);之后在系統(tǒng)任何地方使用的都是這個SensorService實例。最后run()函數(shù)調(diào)用Looper.loop();就進行消息循環(huán)等待了,這就是SystemServer進程的消息服務(wù)了。這才真正叫做系統(tǒng)服務(wù)嘛。我們繼續(xù)看SensorManager類的構(gòu)造函數(shù),取得SensorService后, nativeClassInit();這是一個jni函數(shù),SensorManager類調(diào)用的jni函數(shù)都在com_android_server_SensorService.cpp里,我們看這函數(shù)static voidnativeClassInit (JNIEnv *_env, jclass _this) jclass sensorClass = _env-FindClass(android/hardware/Sensor); SensorOffsets& sensorOffsets = gSensorOffsets; sensorO = _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); sensorOffsets.range = _env-GetFieldID(sensorClass, mMaxRange, F); sensorOffsets.resolution = _env-GetFieldID(sensorClass, mResolution,F); sensorOffsets.power = _env-GetFieldID(sensorClass, mPower, F);這個函數(shù)只是獲取和設(shè)置一些信息吧,我們不關(guān)心。接著 sensors_module_init();我們看這函數(shù)static jintsensors_module_init(JNIEnv *env, jclass clazz) int err = 0; sensors_module_t const* module; err = hw_get_module(SENSORS_HARDWARE_MODULE_ID, (const hw_module_t *)&module); if (err = 0) sSensorModule = (sensors_module_t*)module; return err;它獲取了sensor的模塊信息,并把它賦給sSensorModule全局變量,之后傳的modules參數(shù)都為這個。接著在構(gòu)造函數(shù)里 final ArrayList fullList = sFullSensorsList; int i = 0; do Sensor sensor = new Sensor(); i = sensors_module_get_next_sensor(sensor, i); if (i=0) Log.d(TAG, found sensor: + sensor.getName() + , handle= + sensor.getHandle(); sensor.setLegacyType(getLegacySensorType(sensor.getType(); fullList.add(sensor); sHandleToSensor.append(sensor.getHandle(), sensor); while (i0);這里主要是通過jni函數(shù)sensors_module_get_next_sensor(sensor, i);獲取傳感器列表,并把它加入自己的fullList列表中。我們看sensors_module_get_next_sensor()函數(shù)static jintsensors_module_get_next_sensor(JNIEnv *env, jobject clazz, jobject sensor, jint next) if (sSensorModule = NULL) return 0; SensorOffsets& sensorOffsets = gSensorOffsets; const struct sensor_t* list; int count = sSensorModule-get_sensors_list(sSensorModule, &list); if (next = count) return -1; list += next; jstring name = env-NewStringUTF(list-name); jstring vendor = env-NewStringUTF(list-vendor); env-SetObjectField(sensor, sensorO, name); env-SetObjectField(sensor, sensorOffsets.vendor, vendor); env-SetIntField(sensor, sensorOffsets.version, list-version); env-SetIntField(sensor, sensorOffsets.handle, list-handle); env-SetIntField(sensor, sensorOffsets.type, list-type); env-SetFloatField(sensor, sensorOffsets.range, list-maxRange); env-SetFloatField(sensor, sensorOffsets.resolution, list-resolution); env-SetFloatField(sensor, sensorOffsets.power, list-power); next+; return next它主要是調(diào)用HAL層的get_sensors_list()函數(shù)取得傳感器列表信息。接著在sensorManger構(gòu)造函數(shù)最后 sSensorThread = new SensorThread();創(chuàng)建一個SensorThread()線程。但并未運行,但在SensorThread類的構(gòu)造函數(shù)里會執(zhí)行jni函數(shù) sensors_data_init();我們看此函數(shù)static jintsensors_data_init(JNIEnv *env, jclass clazz) if (sSensorModule = NULL) return -1; int err = sensors_data_open(&sSensorModule-common, &sSensorDevice); return err;它調(diào)用了HAL層的sensors_data_open函數(shù),而這個函數(shù)位于sensor.h中,它調(diào)用的是static inline int sensors_data_open(const struct hw_module_t* module, struct sensors_data_device_t* device) return module-methods-open(module, SENSORS_HARDWARE_DATA, (struct hw_device_t*)device);Modules-methods-open函數(shù)。而在SensorThread類的析構(gòu)函數(shù)finalize()里會調(diào)用 sensors_data_uninit();static jintsensors_data_uninit(JNIEnv *env, jclass clazz) int err = 0; if (sSensorDevice) err = sensors_data_close(sSensorDevice); if (err = 0) sSensorDevice = 0; return err;在sensor.h里static inline int sensors_data_close(struct sensors_data_device_t* device) return device-common.close(&device-common);那什么時候sSensorThread線程會運行呢?我們在下面看registerListener()函數(shù)。(2) public boolean registerListener(SensorEventListener listener, Sensor sensor, int rate) return registerListener(listener, sensor, rate, null);它調(diào)用的是 public boolean registerListener(SensorEventListener listener, Sensor sensor, int rate, Handler handler)在這函數(shù)中,先驗證rate,然后檢測注冊的listener在不在本類的sListeners列表中。 for (ListenerDelegate i : sListeners) if (i.getListener() = listener) l = i; break; 如果不在就申請一個listener,并把它加入全局列表sListener中,并調(diào)用mSensorService的enableSensor()函數(shù)使能傳感器,這個enableSensor()函數(shù)最終會調(diào)用HAL層的active函數(shù)和set_delay()函數(shù),使用后然后判斷sListener列表是否為空,當然,第一次為空時加入一個新的listener就不為空了,此時就執(zhí)行sSensorThread的startLocked運行sSensorThread線程了 l = new ListenerDelegate(listener, sensor, handler); result = mSensorService.enableSensor(l, name, handle, delay); if (result) sListeners.add(l); sListeners.notify(); if (!sListeners.isEmpty() sSensorThread.startLocked(mSensorService); 另一方面,如果注冊的listener在sListeners列表中,則先調(diào)用mSensorService的enableSensor()函數(shù)使能傳感器,然后把注冊的傳感器加入到已存在的listener中。 result = mSensorService.enableSensor(l, name, handle, delay); if (result) l.addSensor(sensor); 接下來我們看看startLocked函數(shù),它在SensorThread中, void startLocked(ISensorService service) try if (mThread = null) Bundle dataChannel = service.getDataChannel(); mThread = new Thread(new SensorThreadRunnable(dataChannel), SensorThread.class.getName(); mThread.start(); catch (RemoteException e) Log.e(TAG, RemoteException in startLocked: , e); 第一次mThread為null,然后它調(diào)用了service.getDataChannel()函數(shù),此函數(shù)在SensorService類中,主要調(diào)用了jni函數(shù)_sensors_control_open(), public Bundle getDataChannel() throws RemoteException / synchronize so we do not require sensor HAL to be thread-safe. synchronized(mListeners) return _sensors_control_open(); SensorService類中調(diào)用的jni函數(shù)主要都在com_android_server_SensorService.cpp文件 中,我們看一下這個函數(shù)static jobjectandroid_open(JNIEnv *env, jclass clazz) native_handle_t* handle = sSensorDevice-open_data_source(sSensorDevice); if (!handle) return NULL; / new Bundle() jobject bundle = env-NewObject( gBundleOffsets.mClass, gBundleOffsets.mConstructor); if (handle-numFds 0) jobjectArray fdArray = env-NewObjectArray(handle-numFds, gParcelFileDescriptorOffsets.mClass, NULL); for (int i = 0; i numFds; i+) / new FileDescriptor() jobject fd = env-NewObject(gFileDescriptorOffsets.mClass, gFileDescriptorOffsets.mConstructor); env-SetIntField(fd, gFileDescriptorOffsets.mDescriptor, handle-datai); / new ParcelFileDescriptor() jobject pfd = env-NewObject(gParcelFileDescriptorOffsets.mClass, gParcelFileDescriptorOffsets.mConstructor, fd); env-SetObjectArrayElement(fdArray, i, pfd); / bundle.putParcelableArray(fds, fdArray); env-CallVoidMethod(bundle, gBundleOffsets.mPutParcelableArray, env-NewStringUTF(fds), fdArray); if (handle-numInts 0) jintArray intArray = env-NewIntArray(handle-numInts); env-SetIntArrayRegion(intArray, 0, handle-numInts, &handle-datahandle-numInts); / bundle.putIntArray(ints, intArray); env-CallVoidMethod(bundle, gBundleOffsets.mPutIntArray, env-NewStringUTF(ints), intArray); / delete the file handle, but dont close any file descriptors native_handle_delete(handle); return bundle;它主要調(diào)用了HAL層的open_data_source()函數(shù)。取得一些文件描述符等信息。接下來SensorThread創(chuàng)建一個線程,調(diào)用start()就進入SensorThreadRunnable類的run()函數(shù)了,所以我們接著去看run()函數(shù),它首先調(diào)用open()函數(shù) if (!open() return; 在open()函數(shù)中調(diào)用了 jni函數(shù)sensors_data_open(fds, ints);static jintsensors_data_open(JNIEnv *env, jclass clazz, jobjectArray fdArray, jintArray intArray) jclass FileDescriptor = env-FindClass(java/io/FileDescriptor); jfieldID fieldOffset = env-GetFieldID(FileDescriptor, descriptor, I); int numFds = (fdArray ? env-GetArrayLength(fdArray) : 0); int numInts = (intArray ? env-GetArrayLength(intArray) : 0); native_handle_t* handle = native_handle_create(numFds, numInts); int offset = 0; for (int i = 0; i GetObjectArrayElement(fdArray, i); if (fdo) handle-dataoffset+ = env-GetIntField(fdo, fieldOffset); else handle-dataoffset+ = -1; if (numInts 0) jint* ints = env-GetIntArrayElements(intArray, 0); for (int i = 0; i dataoffset+ = intsi; env-ReleaseIntArrayElements(intArray, ints, 0); / doesnt take ownership of the native handle return sSensorDevice-data_open(sSensorDevice, handle);這函數(shù)最終調(diào)用了HAL層的data_open(),之后run()函數(shù)就進入一個while循環(huán)了。 while (true) / wait for an event final int sensor = sensors_data_poll(values, status, timestamp); int accuracy = status0; synchronized (sListeners) if (sensor = -1 | sListeners.isEmpty() if (sensor = -1) / we lost the connection to the event stream. this happens / when the last listener is removed. Log.d(TAG, _sensors_data_poll() failed, we ba
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 公司辦公品管理制度
- 公司護衛(wèi)犬管理制度
- 公司董事會管理制度
- 冰箱廠安全管理制度
- 員工洗衣間管理制度
- 學校防墜落管理制度
- 小企業(yè)飲料管理制度
- 小食品公司管理制度
- 旅游分公司管理制度
- 柴油機空載管理制度
- 海氏(hay)職位分析法-介紹、實踐與評價合集課件
- 有趣的英漢互譯-課件
- 潔凈區(qū)空氣潔凈度級別空氣懸浮粒子的標準規(guī)定表
- 人教版五年級下冊期末語文試卷答題卡及答案
- 步進式加熱爐耐材砌筑施工方案
- GB-T12232-2005- 通用閥門 法蘭連接鐵制閘閥
- 2022年中國電信店長技能四級認證教材
- (最新整理)《跨文化溝通》PPT課件
- 怎樣分析日本氣象傳真圖
- 常見散料堆積密度匯總-共10
- 視頻監(jiān)控巡查記錄
評論
0/150
提交評論