<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>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                # Android用戶事件輸入路徑 ### 1 輸入路徑的一般原理 按鍵,鼠標消息從收集到最終將發送到焦點窗口,要經歷怎樣的路徑,是Android GWES設計方案中需要詳細考慮的問題。按鍵,鼠標等用戶消息消息的處理可分為不同的情況進行判定: (1)用戶輸入根據系統狀況是否應該派送。如在ScreenOff的情況下,在按鍵屬于特殊按鍵的情況下等 (2)是否有攔截Listener (3)對按鍵事件來講,是否存在輸入法 (4)是否是焦點終點 (5)是否為焦點切換按相關鍵 這些情況都是設計輸入路徑需要考慮的基本條件。 ### 1.1一般的輸入路徑設計 該輸入路徑實際上是指的按鍵消息(MSG_KEYDOWN,MSG_KEYUP, MSG_LongPress)的輸入路徑,即從活動主窗口到焦點窗口所經歷的路程。 [![inputNormal](https://box.kancloud.cn/2016-05-05_572b1a1dd5670.gif "inputNormal")](http://hi.csdn.net/attachment/201005/5/0_1273072314A4ZR.gif) 將信息輸入路徑分為兩步: Step 1)窗口管理器將信息發送到活動窗口 Step 2)活動窗口通過缺省處理函數將該消息一層層的傳遞到焦點。 這樣應用程序可以在活動View的處理函數中來預先處理用戶輸入信息,從而增強應用對用戶信息的控制力。 [![inputxxx1](https://box.kancloud.cn/2016-05-05_572b1a1de9a7e.gif "inputxxx1")](http://hi.csdn.net/attachment/201005/5/0_1273072315h9Yf.gif) 傳遞路徑是通過View的缺省處理函數Onxxx來完成。通過ActiveView ->focus->focus->focus的鏈條關系,一級一級的將按鍵消息MSG_KEYDOWN,MSG_KEYUP, MSG_CHAR等傳遞到focus窗口。 [![inputxxx2](https://box.kancloud.cn/2016-05-05_572b1a1e0add6.gif "inputxxx2")](http://hi.csdn.net/attachment/201005/5/0_1273072316MABo.gif) 此時用戶按鍵輸入先發送到輸入法窗口,經過輸入法管理器處理,過濾后將輸入法產生的結果放置到焦點View。 ### 1.3輸入系統整體流程 下面示意圖是Android輸入系統的數據流途徑,通過WM的輸入系統線程收集消息,分發到Focus Activity消息隊列,然后通過消息系統派發。 [![InputSystemPATH](https://box.kancloud.cn/2016-05-05_572b1a1e1dbd1.gif "InputSystemPATH")](http://hi.csdn.net/attachment/201005/5/0_1273072319mmM9.gif) ### 2 Android輸入路徑詳細描述 ### 2.1 第一步:用戶數據收集及其初步判定 KeyInputQ在WindowMangerService中建立一個獨立的線程InputDeviceReader,使用Native函數readEvent來讀取Linux Driver的數據構建RawEvent,放入到KeyQ消息隊列中。 [![inputDeviceReader](https://box.kancloud.cn/2016-05-05_572b1a1e37e4c.gif "inputDeviceReader")](http://hi.csdn.net/attachment/201005/5/0_1273072322wE2w.gif) preProcessEvent()@KeyInptQ@KeyInputQueue.java這個是在輸入系統中的第一個攔截函數原型。KeyQ重載了preProcessEvent()@WindowManagerService.java。在該成員函數中進行如下動作: (1) 根據PowerManager獲取的Screen on,Screen off狀態來判定用戶輸入的是否WakeUPScreen。 (2) 如果按鍵式應用程序切換按鍵,則切換應用程序。 (3) 根據WindowManagerPolicy覺得該用戶輸入是否投遞。 ### 2.2 第二步 消息分發第一層面 InputDispatcherThread從KeyQ中讀取Events,找到Window Manager中的Focus Window,通過Focus Window記錄的mClient接口,將Events專遞到Client端。 [![inputDispatcherThread](https://box.kancloud.cn/2016-05-05_572b1a1e48299.gif "inputDispatcherThread")](http://hi.csdn.net/attachment/201005/5/0_12730723237679.gif) 如何將KeyEvent對象傳到Client端: 在前面的章節(窗口管理ViewRoot,Window Manager Proxy)我們已經知道:在客戶端建立Window Manager Proxy后,添加窗口到Window Manager service時,帶了一個跟客戶ViewRoot相關的IWindow接口實例過去,記錄在WindowState中的mClient成員變量中。通過IWindow這個AIDL接口實例,Service可以訪問客戶端的信息,IWindow是Service連接View橋梁。 [![IWindow](https://box.kancloud.cn/2016-05-05_572b1a1e5a7e7.gif "IWindow") ](http://hi.csdn.net/attachment/201005/5/0_1273072324aNrZ.gif) 看看在Client ViewRootKeyEvent的分發過程 IWindow:dispatchKey(event) dispatchKey(event)@W@ViewRoot@ViewRoot.java ViewRoot.dispatchKey(event)@ViewRoot.java <message> sendMessageAtTime(msg)@Handler@Handler.java 至此我們通過前面的Looper,Handler詳解章節的分析結論,我們可以知道Key Message已經放入到應用程序的消息隊列。 ### 2.3第三步:應用消息隊列分發 消息的分發,在Looper,Handler詳解章節我們分析了Looper.loop()在最后后面調用了handleMesage. … ActivityThread.main() Looper.loop() ViewRoot$RootHandler().dispatch() handleMessage .... 注意到在分發的調用msg.target.dispatch(),而這個target在第二層將消息sendMessageAtTime到消息隊列時填入了mag.target=this即為msg.target=ViewRoot實例。所有此時handleMessage就是ViewRoot重載的handleMessage函數。 handlerMessage@ViewRoot@ViewRoot.java deliverkeyEvent 如果輸入法存在,dispatchKey到輸入法服務。 否則[deliverKeyEventToViewHierarchy@ViewRoot.java](#) 在這里需要強調的是,輸入法的KeyEvent的攔截并沒有放入到Window Manager Service中,而是放入到了客戶端的RootView中來處理。 ### 2.4第四步:向焦點進發,完成焦點路徑的遍歷。 [](#)[![focuspath1](https://box.kancloud.cn/2016-05-05_572b1a1e704ce.gif "focuspath1") ](http://hi.csdn.net/attachment/201005/5/0_12730723266xTM.gif) 分發函數調用棧 [deliverKeyEventToViewHierarchy@ViewRoot.java](#) mView.dispatchKeyEvent:mView是與ViewRoot相對應的Top-Level View.如果mView是一個ViewGroup則分發消息到他的mFocus。 mView.dispatchKeyEvent @ViewGroup? (ViewRoot@root) Event.dispatch mFocus.dispatchKeyEevnet 如果此時的mFocu還是一個ViewGroup,這回將事件專遞到下一層的焦點,直到mFocus為一個View。通過這輪調用,就遍歷了焦點Path,至此,用戶事件傳遞完成一個段落。 ### 2.5第五步 缺省處理 如果事件在上述Focus View沒有處理掉,并且為方向鍵之類的焦點轉換相關按鍵,則轉移焦點到下一個View。
                  <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>

                              哎呀哎呀视频在线观看