Android面試題--事件處理

来源:http://www.cnblogs.com/wuyudong/archive/2016/10/14/5960564.html
-Advertisement-
Play Games

1、Handler 機制 Android 中主線程也叫 UI 線程,那麼從名字上我們也知道主線程主要是用來創建、更新 UI 的,而其他耗時操作,比如網路訪問,或者文件處理,多媒體處理等都需要在子線程中操作,之所以在子線程中操作是為了保證 UI 的流暢程度,手機顯示的刷新頻率是 60Hz,也就是一秒鐘 ...


1、Handler 機制

Android 中主線程也叫 UI 線程,那麼從名字上我們也知道主線程主要是用來創建、更新 UI 的,而其他耗時操作,比如網路訪問,或者文件處理,多媒體處理等都需要在子線程中操作,之所以在子線程中操作是為了保證 UI 的流暢程度,手機顯示的刷新頻率是 60Hz,也就是一秒鐘刷新 60 次,每16.67 毫秒刷新一次,為了不丟幀,那麼主線程處理代碼最好不要超過 16 毫秒。當子線程處理完數據後,為了防止 UI 處理邏輯的混亂,Android 只允許主線程修改 UI,那麼這時候就需要 Handler來充當子線程和主線程之間的橋梁了。
我們通常將 Handler 聲明在 Activity 中,然後覆寫 Handler 中的 handleMessage 方法,當子線程調用 handler.sendMessage()方法後 handleMessage 方法就會在主線程中執行。這裡面除了 Handler、Message 外還有隱藏的 Looper 和 MessageQueue 對象。在主線程中 Android 預設已經調用了 Looper.preper()方法,調用該方法的目的是在 Looper 中創 建 MessageQueue 成 員 變 量 並 把 Looper對象綁定到當前線程中。 當調用 Handler 的sendMessage(對象)方法的時候就將 Message 對象添加到了 Looper 創建的 MessageQueue隊列中,同時給 Message 指定了 target 對象,其實這個 target 對象就是 Handler 對象。主線程默
認執行了 Looper.looper () 方法, 該方法從 Looper 的成員變數 MessageQueue 中取出 Message,然後調用 Message 的 target 對象的 handleMessage()方法。這樣就完成了整個消息機制。

2、事件分發機制

2.1 事件分發中的 onTouch 和 onTouchEvent 有什麼區別,又該如何使用?
這兩個方法都是在 View 的 dispatchTouchEvent 中調用的,onTouch 優先於 onTouchEvent執行。如果在 onTouch 方法中通過返回 true 將事件消費掉,onTouchEvent 將不會再執行。另外需要註意的是,onTouch 能夠得到執行需要兩個前提條件,第一 mOnTouchListener 的值不能為空,第二當前點擊的控制項必須是 enable 的。因此如果你有一個控制項是非 enable 的,那麼給它註冊 onTouch 事件將永遠得不到執行。對於這一類控制項,如果我們想要監聽它的 touch 事件,就必須通過在該控制項中重寫 onTouchEvent 方法來實現。

2.2 請描述一下 Android 的事件分發機制

Android 的事件分發機制主要是 Touch 事件分發,有兩個主角:ViewGroup 和 View。Activity的 Touch 事件事實上是調用它內部的 ViewGroup 的 Touch 事件,可以直接當成 ViewGroup 處理。View 在 ViewGroup 內, ViewGroup 也可以在其他 ViewGroup 內, 這時候把內部的 ViewGroup當成 View 來分析。
先分析 ViewGroup 的處理流程:首先得有個結構模型概念:ViewGroup 和 View 組成了一棵樹形結構,最頂層為 Activity 的 ViewGroup,下麵有若幹的 ViewGroup 節點,每個節點之下又有若幹的 ViewGroup 節點或者 View 節點,依次類推。如圖:

 

當一個 Touch 事件(觸摸事件為例)到達根節點,即 Acitivty 的 ViewGroup 時,它會依次下發,下發的過程是調用子 View(ViewGroup)的 dispatchTouchEvent 方法實現的。簡單來說,就是ViewGroup 遍歷它包含著的子 View,調用每個 View 的 dispatchTouchEvent 方法,而當子 View為 ViewGroup 時,又會通過調用 ViwGroup 的 dispatchTouchEvent 方法繼續調用其內部的 View的 dispatchTouchEvent 方法。上述例子中的消息下發順序是這樣的:①-②-⑤-⑥-⑦-③-④。
dispatchTouchEvent 方法只負責事件的分發,它擁有 boolean 類型的返回值,當返回為 true 時,順序下發會中斷。在上述例子中如果⑤的dispatchTouchEvent 返回結果為 true,那麼⑥-⑦-③-④將都接收不到本次 Touch 事件。

1.Touch 事 件 分 發 中 只 有 兩 個 主 角 :ViewGroup 和 View。ViewGroup 包 含onInterceptTouchEvent 、 dispatchTouchEvent、onTouchEvent 三個相關事件。 View包含dispatchTouchEvent、onTouchEvent 兩個相關事件。其中 ViewGroup 又繼承於 View。

2.ViewGroup 和 View 組成了一個樹狀結構,根節點為 Activity 內部包含的一個 ViwGroup。

3.觸摸事件由 Action_Down、Action_Move、Aciton_UP 組成,其中一次完整的觸摸事件中,Down 和 Up 都只有一個,Move 有若幹個,可以為 0 個。

4.當 Acitivty 接收到 Touch 事件時,將遍歷子 View 進行 Down 事件的分發。ViewGroup 的遍歷可以看成是遞歸的。分發的目的是為了找到真正要處理本次完整觸摸事件的 View,這個 View 會在 onTouchuEvent 結果返回 true。

5.當某個子 View 返回 true 時, 會中止 Down 事件的分發, 同時在 ViewGroup 中記錄該子 View。接下去的 Move 和 Up 事件將由該子 View 直接進行處理。 由於子 View 是保存在 ViewGroup 中的,多層 ViewGroup 的節點結構時,上級 ViewGroup 保存的會是真實處理事件的 View 所在的ViewGroup 對象:如 ViewGroup0-ViewGroup1-TextView 的結構中,TextView 返回了 true,它將被保存在 ViewGroup1 中,而 ViewGroup1 也會返回 true,被保存在ViewGroup0 中。當 Move和 UP 事件來時,會先從 ViewGroup0 傳遞至 ViewGroup1,再由 ViewGroup1 傳遞至 TextView。

6.當 ViewGroup 中所有子 View 都不捕獲 Down 事件時,將觸發 ViewGroup 自身的 onTouch事件。觸發的方式是調用 super.dispatchTouchEvent 函數,即父類 View 的 dispatchTouchEvent方法。在所有子 View 都不處理的情況下,觸發 Acitivity 的 onTouchEvent 方法。
7.onInterceptTouchEvent 有兩個作用:1.攔截 Down 事件的分發。2.中止 Up 和 Move 事件向目標 View 傳遞,使得目標 View 所在的 ViewGroup 捕獲 Up 和 Move 事件。

3、子線程發消息到主線程進行更新 UI,除了 handler 和 AsyncTask,還有什麼?

(1)用 Activity 對象的 runOnUiThread 方法更新在子線程中通過 runOnUiThread()方法更新 UI:

(2)用 View.post(Runnable r)方法更新 UI

4、子線程中能不能 new handler?為什麼?

不能,如果在子線程中直接 new Handler()會拋出異常 java.lang.RuntimeException: Can't create handler inside thread that has not called

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 今天做form表單提交遇到了兩個問題: 1.提交後不能跳轉到指定頁面 jsp代碼 js提交事件處理: 這種寫法在頁面點擊保存後在當前頁面跳轉, 而不執行post請求function(data){}中的方法:window.history.back()返回到上一級歷史頁面,分析原因是button的typ ...
  • 最近在使用jquery.form.js提交包含文件的表單時,碰到了一個問題:當碰上網速較慢時,而我們又設置了timeout時,例如: 我們的頁面會死在這裡,貼上F12開發者工具返回的結果: 此時,我們並沒有處理錯誤的回調函數,而百度出來的例子中也只有這兩個回調函數: beforeSubmit: sh ...
  • react實例之todo, 做一個實時響應的列表操作 在所有的mvc框架中,最常見的例子不是hello world,而是todo,由於reactjs的簡單性,在不引用flux和redux的情況下,我們也一樣可以做出很好的效果來。 本文的例子在react中國首頁中可以看到,它的源代碼請點擊這裡http ...
  • 對於一個從後臺轉到前端的web開發者來說,最大的麻煩就是寫CSS,瞭解CSS的人都知道,它可以開髮網頁樣式,但是沒法用它編程,感覺耦合性相當的高,如果想要方便以後維護,只能逐句修改甚至重寫相當一部分的CSS。隨著後臺人員大量的涌入前端這個行業,CSS又煥發了新的春天,人們開始為CSS加入編程元素,也 ...
  • 讓前端程式更具可維護性,是一個老生常談的問題,大多數時候我們都關註於應用層面的代碼可維護性,如:OO、模塊化、MVC,編碼規範、可擴展和復用性,但這都是屬於設計層面需要考慮的事情,可維護性還應包含另一個方面,也是很多coder容易忽略的地方,就是將自己寫的程式以文檔的形式沉澱起來,對自己工作有一個結 ...
  • Android系統下的基本數據存儲形式,文件存儲、sp存儲、資料庫存儲、網路存儲、Content Provider記憶體提供者 ...
  • 一.使用HttpURLConnection提交數據 "get"請求 代碼: String path = "http://地址?數據1名字=" + URLEncoder.encode(數據1,"utf-8") + "&數據2名字=" +URLEncoder.encode(數據2,"utf-8"); U ...
  • 記憶體錯誤crash現場: Thread堆棧: 有可能是訪問被釋放對象造成,根據現場並不能找到具體哪個對象出現記憶體錯誤。 1.開啟僵屍對象調試 Edit Scheme->Debug->Diagnostics->Enable Zombie Objects 2.閃退後查看控制台,看輸出應該是某個Butto ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...