<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                同以往一樣,本節通過IMS的啟動過程,探討IMS的構成。上一節提到,IMS分為Java層與Native層兩個部分,其啟動過程是從Java部分的初始化開始,進而完成Native部分的初始化。 #### 1. IMS的誕生 同其他系統服務一樣,IMS在SystemServer中的ServerThread線程中啟動。 **SystemServer.java-->ServerThread.run()** ``` public void run() { ...... InputManagerService inputManager = null; ...... // **① 新建IMS對象。**注意第二個參數wmHandler,這說明IMS的一部分功能可能會在WMS的線程中完成 inputManager= new InputManagerService(context, wmHandler); // 將IMS發布給ServiceManager,以便其他人可以訪問IMS提供的接口 ServiceManager.addService(Context.INPUT_SERVICE,inputManager); // 設置向WMS發起回調的callback對象 inputManager.setWindowManagerCallbacks(wm.getInputMonitor()); // **② 正式啟動IMS** inputManager.start(); ...... /* 設置IMS給DisplayManagerService。DisplayManagerService將會把屏幕的信息發送給輸入 系統作為事件加工的依據。在5.2.4節將會討論到這些信息的作用 */ display.setInputManager(inputManager); } ``` IMS的誕生分為兩個階段: - 創建新的IMS對象。 - 調用IMS對象的start()函數完成啟動。 ##### (1) IMS的創建 IMS的構造函數如下: **InputManagerService.java-->InputManagerService.InputManagerService()** ``` public InputManagerService(Context context,Handler handler) { /* 使用wmHandler的Looper新建一個InputManagerHandler。InputManagerHandler將運行在 WMS的主線程中*/ this.mHandler = new InputManagerHandler(handler.getLooper()); ...... // 每一個分為Java和Native兩部分的對象在創建時都會有一個nativeInput函數 mPtr =nativeInit(this, mContext, mHandler.getLooper().getQueue()); } ``` 可以看出,IMS的構造函數非常簡單。看來絕大部分的初始化工作都位于Native層。參考nativeInit()函數的實現。 **com_android_server_input_InputManagerService.cpp-->nativeInit()** ``` static jint nativeInit(JNIEnv* env, jclass clazz, jobject serviceObj, jobject contextObj, jobject messageQueueObj) { sp<MessageQueue> messageQueue =android_os_MessageQueue_getMessageQueue(env, messageQueueObj); /* 新建了一個NativeInputManager對象,NativeInputManager,此對象將是Native層組件與 Java層IMS進行通信的橋梁 */ NativeInputManager* im = new NativeInputManager(contextObj, serviceObj, messageQueue->getLooper()); im->incStrong(serviceObj); // 返回了NativeInputManager對象的指針給Java層的IMS,IMS將其保存在mPtr成員變量中 returnreinterpret_cast<jint>(im); } ``` nativeInit()函數創建了一個類型為NativeInputManager的對象,它是Java層與Native層互相通信的橋梁。 看下這個類的聲明可以發現,它實現了InputReaderPolicyInterface與InputDispatcherPolicyInterface兩個接口。這說明上一節曾經介紹過的兩個重要的輸入系統參與者InputReaderPolicy和InputDispatcherPolicy是由NativeInputManager實現的,然而它僅僅為兩個策略提供接口實現而已,并不是策略的實際實現者。NativeInputManager通過JNI回調Java層的IMS,由它完成決策。這一小節暫不討論其實現細節,讀者只要先記住兩個策略參與者的接口實現位于NativeInputManager即可。 接下來看一下NativeInputManager的創建: **com_android_server_input_InputManagerService.cpp-->NativeInputManager::NativeInputManager()** ``` NativeInputManager::NativeInputManager(jobjectcontextObj, jobject serviceObj, const sp<Looper>& looper) : mLooper(looper) { ...... // 出現重點了, NativeInputManager創建了EventHub sp<EventHub> eventHub = new EventHub(); // 接著創建了Native層的InputManager mInputManager = new InputManager(eventHub, this, this); } ``` 在NativeInputManager的構造函數中,創建了兩個關鍵人物,分別是EventHub與InputManager。EventHub復雜的構造函數使其在創建后便擁有了監聽設備節點的能力,這一小節中暫不討論它的構造函數,讀者僅需知道EventHub在這里初始化即可。緊接著便是InputManager的創建了,看一下其構造函數: **InputManager.cpp-->InputManager::InputManager()** ``` InputManager::InputManager( const sp<EventHubInterface>& eventHub, const sp<InputReaderPolicyInterface>& readerPolicy, const sp<InputDispatcherPolicyInterface>& dispatcherPolicy) { // 創建InputDispatcher mDispatcher = new InputDispatcher(dispatcherPolicy); // 創建 InputReader mReader= new InputReader(eventHub, readerPolicy, mDispatcher); // 初始化 initialize(); } ``` 再看initialize()函數: **InputManager.cpp-->InputManager::initialize()** ``` void InputManager::initialize() { // 創建供InputReader運行的線程InputReaderThread mReaderThread = new InputReaderThread(mReader); // 創建供InputDispatcher運行的線程InputDispatcherThread mDispatcherThread = new InputDispatcherThread(mDispatcher); } ``` InputManager的構造函數也比較簡潔,它創建了四個對象,分別為IMS的核心參與者InputReader與InputDispatcher,以及它們所在的線程InputReaderThread與InputDispatcherThread。注意InputManager的構造函數的參數readerPolicy與dispatcherPolicy,它們都是NativeInputManager。 至此,IMS的創建完成了。在這個過程中,輸入系統的重要參與者均完成創建,并得到了如圖5-2所描述的一套體系。 :-: ![](http://img.blog.csdn.net/20150814132701337?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center) 圖 5-2 IMS的結構體系 ##### (2) IMS的啟動與運行 完成IMS的創建之后,ServerThread執行了InputManagerService.start()函數以啟動IMS。InputManager的創建過程分別為InputReader與InputDispatcher創建了承載它們運行的線程,然而并未將這兩個線程啟動,因此IMS的各員大將仍處于待命狀態。此時start()函數的功能就是啟動這兩個線程,使得InputReader于InputDispatcher開始工作。 當兩個線程啟動后,InputReader在其線程循環中不斷地從EventHub中抽取原始輸入事件,進行加工處理后將加工所得的事件放入InputDispatcher的派發發隊列中。InputDispatcher則在其線程循環中將派發隊列中的事件取出,查找合適的窗口,將事件寫入到窗口的事件接收管道中。窗口事件接收線程的Looper從管道中將事件取出,交由事件處理函數進行事件響應。整個過程共有三個線程首尾相接,像三臺水泵似的一層層地將事件交付給事件處理函數。如圖5-3所示。 :-: ![](http://img.blog.csdn.net/20150814132715787?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center) 圖 5-3 三個線程,三臺水泵 InputManagerService.start()函數的作用,就像為Reader線程、Dispatcher線程這兩臺水泵按下開關,而Looper這臺水泵在窗口創建時便已經處于運行狀態了。自此,輸入系統動力十足地開始運轉,設備節點中的輸入事件將被源源不斷地抽取給事件處理者。本章的主要內容便是討論這三臺水泵的工作原理。 #### 2. IMS的成員關系 根據對IMS的創建過程的分析,可以得到IMS的成員關系如圖5-4所示,這幅圖省略了一些非關鍵的引用與繼承關系。 **注意** IMS內部做了很多的抽象工作,EventHub、nputReader以及InputDispatcher等實際上都繼承自相應的名為XXXInterface的接口,并且僅通過接口進行相互之間的引用。鑒于這些接口各自僅有唯一的實現,為了簡化敘述我們將不提及這些接口,但是讀者在實際學習與研究時需要注意這一點。 :-: ![](http://img.blog.csdn.net/20150814132728051?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center) 圖 5-4 IMS的成員關系 在圖5-4中,左側部分為Reader子系統對應于圖5-3中的第一臺水泵,右側部分為Dispatcher子系統,對應于圖5-3中的第二臺水泵。了解了IMS的成員關系后便可以開始我們的IMS深入理解之旅了!
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看