成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

如何打造穩(wěn)定、好用的 Android LayoutInspector?

移動開發(fā) Android
本文將圍繞 LayoutInspector 的痛點,分析問題并修復(fù),最終將 LayoutInspector 變成一個穩(wěn)定、好用的插件。

一、背景

Android 開發(fā)者在日常的開發(fā)中,經(jīng)常需要用到查看視圖的功能,Android Studio 開發(fā)團隊為我們提供了 LayoutInspector 插件。在較新的版本提供了 LiveLayoutInspector,支持 3D,但是不管是 LayoutInspector 還是 LiveLayoutInspector 都非常難用。比如:

  • 速度極慢,遇到復(fù)雜的布局經(jīng)常超時
  • 某些情況無法選中指定的 View

本文將圍繞 LayoutInspector 的痛點,分析問題并修復(fù),最終將 LayoutInspector 變成一個穩(wěn)定、好用的插件。

二、加速 Dump View Hierarchy

2.1 問題描述

開發(fā)復(fù)雜業(yè)務(wù)的同學(xué)在使用 LayoutInspector 時都遇到過上圖所示的錯誤:由于 View 樹結(jié)構(gòu)復(fù)雜超時。網(wǎng)上也有其他相關(guān)的解決辦法,原理就是修改 timeout 的值,目前默認(rèn)值是 20s,所以改成 1min,大概率是可以的了。

為了更好的解決這個問題,比如是否能加速?我們看一下整個 LayoutInspector 抓取的流程。梳理流程之前,我們需要找到功能的入口。

2.2 問題分析

2.2.1 Dump 總流程

平常開發(fā)者使用 LayoutInspector 的流程一般如下:

  • 和 Attach debugger 類似,先獲取要 LayoutInspector 的進程
  • 如果進程中不止一個 ViewRootImpl,還需要選擇 window

在 IDEA Plugin 框架體系中,大多數(shù)插件的功能入口都依賴 Action,上圖 LayoutInspector 的功能入口對應(yīng)的 Action 如何找到呢?最快速、準(zhǔn)確的辦法就是 Debug,在我們點擊功能入口之前,在 AnAction#actionPerformed 加上斷點。

從 AndroidRunLayoutInspectorAction 出發(fā),我們找到了真正的任務(wù):

  1. LayoutInspectorCaptureTask。 

抓取 View 視圖的關(guān)鍵方法如下:

我們可以看到這里先構(gòu)造了一個 Options,Opentions 中有個參數(shù):ProtocolVersion,目前我們能使用的是 ProtocolVersion.Version1,Goolge 內(nèi)可以通過 StudioFlags 打開 ProtocolVersion.Version2。

capture view 的流程會比較長,涉及到 adb 通信原理,我們先簡單了解一下 adb 通信架構(gòu)。

  • adb server: 運行在我們的 PC 開發(fā)機上,監(jiān)聽 5037 端口
  • adb daemon: 運行在 Android 設(shè)備上
  • adb server 通過 USB/tcp 和 adbd 通信

了解了基本的 adb 通信基礎(chǔ)之后,我們再來看整個 captureview 的原理:

  • 通過 ClientWindow 發(fā)起 loadWindowData 的請求(在這里可以看到默認(rèn)超時時間是 20s)
  • ClinetImpl 收到請求,讓 HandleViewDebug 將本次請求封裝成 JDWP,然后準(zhǔn)備發(fā)送
  • ClientImpl 將數(shù)據(jù)先發(fā)送給本 PC 上的 adb server
  • adb server 將數(shù)據(jù)通過 usb/tcp 透傳給 Android 設(shè)備上的 adbd
  • Android 設(shè)備上的 adbd 根據(jù)之前選擇的進程信息,將信息再透傳給指定的 jdwp 線程
  • jdwp 通過 native 調(diào)用 DDMServer 方法
  • DdmHandleViewDebug 收到請求開始處理
  • 處理完請求后,再通過 socket 返回,LayoutInspector 收到結(jié)果解析后展示

 

參考:debugger.cc

  • https://android.googlesource.com/platform/art/+/android-cts-5.0_r9/runtime/debugger.cc#3778

2.2.2 dump v1 原理

在上圖的流程中可以看到在最后的調(diào)用中,有 dump 和 dumpv2 兩個方法,而且 dump 方法已經(jīng)廢棄了。

 

源碼 ViewDebug.java:

看源碼我們知道 v1 dump 是獲取被 @ExportedProperty 注解作用的 filed 和 method,然后將這些數(shù)據(jù)寫入 ByteArrayOutputStream。比如 View的 padding 屬性:

當(dāng)然也有 method:

上面兩圖中的 category: padding 和 focus 體現(xiàn)在 LayoutInspector 的屬性面板中:

上面看源碼的結(jié)論:v1 是通過反射遍歷所有的 Filed 和 Method。

在我的手機 One Plus7 Android 10 上,View 的 filed 有 487 個,method 有 915 個。寫一段簡單的代碼展示一下僅遍歷耗時:

輸出:

  1. D/View#dump: 10705ms and 692 views 

可以看到我們還沒有添加邏輯,僅僅遍歷耗時都達(dá)到了 10s。

2.2.3 dump v2 原理

  1. 看 ViewDebug#dumpv2: 

 

調(diào)用到了 View#encode:

相比 v1,v2 就很克制了,只返回有限的數(shù)據(jù),需要什么數(shù)據(jù)就獲取什么數(shù)據(jù),但不支持自定義的屬性,相當(dāng)于犧牲了一定的靈活性,加快了 dump 的速度。在靈活性、速度兩個方面,Google 將 v1 和 v2都保留了,并通過 StudioFlags 提供了開關(guān)。

2.3 解決方案

對比完 v1 和 v2 之后,基本可以確定 v2 的速度會快很多了。我們通過自定義 Action,并替換掉原生的 LayoutInspectorCaptureTask,關(guān)鍵是替換下面這個方法:

2.3 效果&收益

v2 相比 v1 速度快了非常多,下面貼一下抖音直播間的 Dump 數(shù)據(jù),設(shè)備:One Plus 7 Android 10.

 

  1. LayoutInspector V1: 18803ms  
  2. LayoutInspector V2: 328ms 

本章節(jié)介紹了如何使用 v2 dump 協(xié)議來加速,下面介紹第二個痛點:某些情況無法選中指定的 View。

三、精確獲取點擊的 View

3.1 問題描述

LayoutInspector 還有一個不盡人意的地方——無法選中指定的 View。舉個例子:

上圖藍(lán)框其實是一個空白的沒有內(nèi)容的 View,這個藍(lán)框蓋在了「收禮」這個紅圈上。在我們點擊這個紅圈的時候,卻是選中的藍(lán)框。

3.2 問題分析

我們首先分析一下 LayoutInspector 的 swing 組件組成:

LayoutInspector 中間圖片的預(yù)覽就是上圖中的 myPreview。為了解決這個問題,我們看一下這個點擊選中的邏輯。IDEA 自定義插件中使用的 GUI 框架是 Java Swing,組件的鼠標(biāo)點擊、鼠標(biāo)移入、鼠標(biāo)退出等事件都可以通過 MouseAdapter 來監(jiān)聽。ViewNodeActiveDisplay 的 MouseAdapter 如下:

查找指定的 View 邏輯:

代碼反映出,LayoutInspector 為了滿足點擊事件消費的順序,是從后往前遍歷的,Z 軸值較大的 View 優(yōu)先消費事件。但是在很多情況,我們更需要通過比較 View 的面積大小,來選中指定的 View。

3.3 解決方案

其實代碼好修復(fù),但是比較麻煩的是,如何替換 ViewNodeActiveDisplay 中g(shù)etNode 和 updateSelection 相關(guān)邏輯呢,我注意到調(diào)用 getNode 的地方都是 click/mouseEnter 等事件,所以我們可以替換掉 MosueAdapter,然后重寫 getNode 和 updateSelection。

 

四、手把手教你搭建 IDEA Plugin 開發(fā)環(huán)境

修復(fù)上述兩個痛點需要新建一個 IDEA Plugin,和一般插件開發(fā)環(huán)境略有不同的是,我們需要依賴 android plugin。

然后在 build.gradle 中添加如下配置:

  1. // See https://github.com/JetBrains/gradle-intellij-plugin/ 
  2. intellij { 
  3.     localPath = "/Users/xx/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-1/202.7231092/Android Studio.app" 
  4.     plugins = ['android'
  5.     updateSinceUntilBuild false 

localPath 填寫你本地的 Android Studio app 路徑。

前面我們提到 LayoutInspector 是 android 插件的一部分,所以這里我們聲明 plugins = ['android']

五、總結(jié)

本文圍繞原生 LayoutInspector 的兩個痛點,介紹了 LayoutInspector 的工作原理,并提出了解決方案,使得原生 LayoutInspector 穩(wěn)定、好用。在文章最后也介紹了如何搭建插件工程,方便未接觸過插件的新人能進入插件的新世界。

責(zé)任編輯:未麗燕 來源: 字節(jié)跳動技術(shù)團隊
相關(guān)推薦

2015-10-27 17:52:40

華為

2017-08-28 08:38:08

云存儲圖片站網(wǎng)盤

2009-12-10 10:11:08

2010-07-06 22:39:16

虛擬交換技術(shù)校園網(wǎng)絡(luò)思科

2010-03-02 14:15:11

Android平臺

2013-06-05 10:40:15

應(yīng)用交付深信服AD

2015-06-02 13:56:29

政務(wù)云平臺寧波華為

2014-05-04 10:30:11

風(fēng)河航空系統(tǒng)

2010-03-04 15:17:26

2009-02-27 14:58:00

2012-11-30 13:06:34

網(wǎng)絡(luò)部署負(fù)載均衡應(yīng)用交付

2017-05-05 11:02:47

華為

2013-09-17 12:26:43

BYOD環(huán)境安全BYOD移動設(shè)備

2012-11-02 11:30:08

飛視美視頻會議網(wǎng)絡(luò)質(zhì)量

2011-12-27 14:06:30

投影儀用戶體驗

2009-05-05 10:32:36

LinuxAndroid技術(shù)基石

2020-12-19 10:45:08

Python代碼開發(fā)

2011-03-10 14:05:19

2009-05-05 08:26:33

GoogleAndroid移動OS
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 韩日免费视频 | av大片在线 | 九九热在线精品视频 | 亚洲欧美日韩国产综合 | 欧美激情精品久久久久久免费 | 色婷婷av一区二区三区软件 | 国产美女一区二区 | 亚洲激情av| 成年人网站在线观看视频 | 色屁屁在线观看 | 国产成人一区二区 | 国产精品视频久久久 | 久久久日韩精品一区二区三区 | av中文在线观看 | 国产视频精品视频 | 青青久久久 | 久久亚洲经典 | 在线视频中文字幕 | 男人天堂视频在线观看 | 久久精品国产一区二区电影 | 日韩免费在线 | 99reav| 韩日有码 | 欧美在线不卡 | 一区欧美| 亚洲视频在线观看 | 日韩精品在线免费观看视频 | 国产高清精品一区二区三区 | 毛色毛片免费看 | 网色| 精品国产乱码久久久久久88av | 久久亚洲一区 | 在线一区二区三区 | 久久国产亚洲 | 精品一区二区三区在线观看 | 日本视频中文字幕 | 亚洲一区二区中文字幕 | 亚洲天堂一区二区 | 奇米影视77 | 综合二区 | 国产欧美日韩久久久 |