欧美三级国产三级日韩三级_亚洲熟妇丰满大屁股熟妇_欧美亚洲成人一区二区三区_国产精品久久久久久模特

Linux/Android——Input系統(tǒng)之frameworks層InputManag - 新聞資訊 - 云南小程序開發(fā)|云南軟件開發(fā)|云南網(wǎng)站建設(shè)-昆明葵宇信息科技有限公司

159-8711-8523

云南網(wǎng)建設(shè)/小程序開發(fā)/軟件開發(fā)

知識

不管是網(wǎng)站,軟件還是小程序,都要直接或間接能為您產(chǎn)生價值,我們在追求其視覺表現(xiàn)的同時,更側(cè)重于功能的便捷,營銷的便利,運營的高效,讓網(wǎng)站成為營銷工具,讓軟件能切實提升企業(yè)內(nèi)部管理水平和效率。優(yōu)秀的程序為后期升級提供便捷的支持!

您當(dāng)前位置>首頁 » 新聞資訊 » 技術(shù)分享 >

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)案例查看更多