知識
不管是網(wǎng)站,軟件還是小程序,都要直接或間接能為您產(chǎn)生價值,我們在追求其視覺表現(xiàn)的同時,更側(cè)重于功能的便捷,營銷的便利,運營的高效,讓網(wǎng)站成為營銷工具,讓軟件能切實提升企業(yè)內(nèi)部管理水平和效率。優(yōu)秀的程序為后期升級提供便捷的支持!
Linux/Android——Input系統(tǒng)之frameworks層InputManag
發(fā)表時間:2020-10-19
發(fā)布人:葵宇科技
瀏覽次數(shù):52
上一篇Linux/Android——input體系之 kernel層 與 frameworks層交互 (五) 中有介紹kernel層一下以及與android這邊f(xié)rameworks層之間的接洽,算是打通android 應(yīng)用層與 kernel驅(qū)動層,半數(shù)個input體系的進修是至關(guān)重要的,個中frameworks層只是簡單記錄了幾個接入點,這里開端分析frameworks層的細(xì)節(jié)部分。
撰寫不易,轉(zhuǎn)載需注明出處:http://blog.csdn.net/jscese/article/details/42392311
input辦事的啟動:
android啟動的時刻會啟動很多個service,這個可以參考SystemServer.java ,會啟動InputManagerService這個辦事:
Slog.i(TAG, "Input Manager"); inputManager = new InputManagerService(context, wmHandler); ... ServiceManager.addService(Context.INPUT_SERVICE, inputManager);
直接看InputManagerService.java中的start函數(shù):
public void start() { Slog.i(TAG, "Starting input manager"); nativeStart(mPtr); //調(diào)用了本處所法,JNI對應(yīng)的cpp 在server下的jni目次下 ... }
這個牽扯到android的server的jni,最開端是在SystemServer中加載android_server這個動態(tài)庫,
至于這個動態(tài)庫的編譯可參考/frameworks/base/services/jni/Android.mk中的內(nèi)容
所以在調(diào)用這個nativeStart辦法時,相干的動態(tài)庫已經(jīng)加載到SystemServer的過程中。
先看下這個start函數(shù)在jni文件中的實現(xiàn),frameworks/base/services/jni/com_android_server_input_InputManagerService.cpp中:
static void nativeStart(JNIEnv* env, jclass clazz, jint ptr) { NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); //這個NativeInputManager 是在膳綾擎InputMangerService構(gòu)造的時刻調(diào)用nativeInit時new出來的 status_t result = im->getInputManager()->start(); //這里是調(diào)用了NativeInputManager中的InputManager中的start辦法,同樣這個InputManager是NativeInputManager構(gòu)造的時刻new出來的 if (result) { jniThrowRuntimeException(env, "Input manager could not be started."); } }
其實熟悉JNI的話,我分析到這里,就應(yīng)當(dāng)差不多了。。對于JNI 不是很懂得的話可以參考我之前的博客:Andorid——ubuntu下的 NDK / JNI
看下NativeInputManager構(gòu)造函數(shù)中的:
sp<EventHub> eventHub = new EventHub(); mInputManager = new InputManager(eventHub, this, this);
這里的JNI部分就不多說了,如今就看這個InputManager的start辦法,膳綾擎提到到Android.mk,可以看到include了一個libinput的動態(tài)庫,
而這個動態(tài)庫的路徑是在/frameworks/base/services/input下,這就清楚明潦攀啦.此目次下有InputManager.cpp . EventHub.cpp等
直接看start:
status_t InputManager::start() { status_t result = mDispatcherThread->run("InputDispatcher", PRIORITY_URGENT_DISPLAY); //這個mDispatcherThread是在InputManager構(gòu)造函數(shù)里調(diào)用initialize初始化,這里很明顯啟動了這個名為InputDispatcher的線程 if (result) { ALOGE("Could not start InputDispatcher thread due to error %d.", result); return result; } result = mReaderThread->run("InputReader", PRIORITY_URGENT_DISPLAY); //同上,開啟線程 if (result) { ALOGE("Could not start InputReader thread due to error %d.", result); mDispatcherThread->requestExit(); return result; } return OK; }
到這里算是看到真面貌的感到,看這兩個線程,字面意思,一個是分發(fā)給input事宜給當(dāng)前的activity的,一個是攫取大年夜基層發(fā)上來的input事宜的
InputDispatcher分發(fā):
大年夜膳綾擎的線程啟動分析:
bool InputDispatcherThread::threadLoop() { mDispatcher->dispatchOnce(); return true; }調(diào)用分發(fā)一次的函數(shù):
void InputDispatcher::dispatchOnce() { nsecs_t nextWakeupTime = LONG_LONG_MAX; { // acquire lock AutoMutex _l(mLock); mDispatcherIsAliveCondition.broadcast(); // Run a dispatch loop if there are no pending commands. // The dispatch loop might enqueue commands to run afterwards. if (!haveCommandsLocked()) { //如不雅有緩存的敕令就調(diào)用下面的runCommand去履行,沒有的話這里去檢查是否有新的input事宜,這里定義一個喚醒時光┞菲握 dispatchOnceInnerLocked(&nextWakeupTime); } // Run all pending commands if there are any. // If any commands were run then force the next poll to wake up immediately. if (runCommandsLockedInterruptible()) { nextWakeupTime = LONG_LONG_MIN; } } // release lock // Wait for callback or timeout or wake. (make sure we round up, not down) nsecs_t currentTime = now(); int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime); mLooper->pollOnce(timeoutMillis); //履行膳綾擎一次分發(fā)之后,就進入了loop,這個loop會持續(xù)的檢測對應(yīng)的管道中是否有內(nèi)容可讀,而別的一個線程InputReader 攫取到input事宜之后就會往這個管道寫入 }
這個是處理input事宜的,后續(xù)分析,先看怎么攫取事宜.
InputReader攫?。?BR>
源碼位于frameworks/base/libs/ui/InputReader.cpp ,開啟線程如下:
bool InputReaderThread::threadLoop() { mReader->loopOnce(); return true; }
這里看這個loopOnce:
void InputReader::loopOnce() { ... size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE); //這里去獲取event事宜 ... if (count) { processEventsLocked(mEventBuffer, count); //如不雅獲取到事宜,就處理 } ... }
可以看到這里就到了獲取event事宜了。上一篇中有提到!
getEvent中會一向read,直到get到event之后,經(jīng)由過程precessevent處理,最終會喚醒膳綾擎介紹到的InputDispatcherThread,通知它有新的事沂攀來了
相關(guān)案例查看更多
相關(guān)閱讀
- 安家微信小程序
- 文山小程序開發(fā)
- 云南省城鄉(xiāng)建設(shè)廳網(wǎng)站
- 網(wǎng)站建設(shè)案例
- 微分銷
- 云南網(wǎng)站建設(shè)制作
- 網(wǎng)站建設(shè)首選公司
- 開發(fā)制作小程序
- 定制小程序開發(fā)
- Web開發(fā)框架
- painter
- 昆明做網(wǎng)站
- 昆明小程序設(shè)計
- 重慶網(wǎng)站建設(shè)公司
- 云南網(wǎng)站建設(shè)快速優(yōu)化
- 云南網(wǎng)站建設(shè)價格
- 做網(wǎng)站
- 分銷系統(tǒng)
- 云南科技公司
- 排名
- 云南網(wǎng)站維護
- 網(wǎng)站建設(shè)列表網(wǎng)
- 微信分銷系統(tǒng)
- 汽車報廢
- 網(wǎng)站上首頁
- 二叉樹
- 云南網(wǎng)站建設(shè)服務(wù)
- 云南網(wǎng)站建設(shè)公司地址
- 霸屏推廣
- 大理網(wǎng)站建設(shè)公司