我要理解 OnClick 消息產(chǎn)生過程

背景

項目遇到點擊事件和動畫開始時機時序問題,在這整理點擊事件產(chǎn)生過程,作備忘。


  • 以下假設已經(jīng)理解單次 Activity.dispatchTouchEvent 流程,包括 ViewGroup 和 View 處理
  • 已知 android.view.View.OnClickListener#onClick 的執(zhí)行時機和 android.view.View#onTouchEvent 不是同一 Message
  • Java 層輸入事件的入口在哪里?

問題

  • 從主線程消息隊列的角度看,從 MessageQueue.next 開始到收到 MotionEvent.Down 和 MotiveEvent.Up 事件的主要流程是怎么樣的?

時序圖

OnClick 來源

  • 由于 Android UI 設計成事件驅(qū)動,主線程會一直在 android.os.Looper#loop 中取 MessageQueue 中的 Message 出來執(zhí)行
  • MessageQueue 每次取一條消息時,先進入 native 層執(zhí)行 native 消息隊列中的消息,再取 Java 層的消息出來執(zhí)行
  • 執(zhí)行 android.os.MessageQueue#nativePollOnce 時進入 native 層,對應 android_os_MessageQueue_nativePollOnce 函數(shù),這時的目的是輪詢 native 層消息隊列是否有需要執(zhí)行的消息
  • 接下來 Looper#pollOnce 中遍歷所有注冊到其中的 LooperCallback,回調(diào)他們的 handleEvent 方法
  • NativeInputEventReceiver 從 InputConsumer 中遍歷當前需要處理的輸入事件
  • 拿到 MotionEvent 后通過 JNIEnv 對象調(diào)用 CallVoidMethod 進入 ART 虛擬機
  • JNIEnv 對象把方法信息交給反射模塊,查找到 InputEventReceiver 類和 ArtMethod 對象,把信息交給 ArtMethod 對象
  • ArtMethod 配置調(diào)用參數(shù),并進入?yún)R編執(zhí)行階段,執(zhí)行 android.view.InputEventReceiver#dispatchInputEvent 對應的機器碼
  • 這時進入了 java 層 android.view.InputEventReceiver#dispatchInputEvent 最后分發(fā)給 Activity 對象
  • 如果從 DOWN 到 UP 時間很短,那么 NativeInputEventReceiver 會回調(diào)兩次 CallVoidMethod 把事件傳遞給 Activity 對象

總結(jié)

  • 了解了主線程在 native 層如何回調(diào) Activity.dispatchTouchEvent 的
  • 下一個問題,InputConsumer 如何取到輸入事件的?用戶點擊屏幕,驅(qū)動層先知道這個信息,然后分發(fā)給應用層。但是源碼在哪里?
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容