Android Studio 自定義Debug變量視圖的方法
我們?cè)谑褂肐ntelliJ的IDE進(jìn)行Debug時(shí),去查看一個(gè)未重寫 toString
方法的對(duì)象需要展開當(dāng)前的視圖層級(jí)才能看到里面的屬性,而通過自定義變量視圖的方式可以直接查看,很大程度上提高Debug的效率。
引出問題
我們?cè)贒ebug查看變量時(shí)通常會(huì)遇到這種情況
此時(shí)我想查看 Goods
對(duì)象里面的具體屬性值,需要點(diǎn)擊左邊的展開按鈕才能查看里面具體的屬性值,不能直接進(jìn)行查看。更糟糕的是當(dāng) Goods
對(duì)象在 List
容器中時(shí),我們?nèi)绻肟焖俨檎业疆?dāng)前 List
里元素的某一項(xiàng)(或幾項(xiàng))屬性時(shí),就會(huì)出現(xiàn)在下面的情況,我們只能逐一元素進(jìn)行展開操作才能查看到元素對(duì)應(yīng)的信息。
重寫toString及其局限性
上述問題的一般解決方式是重寫該類的 toString
方法,然后重新運(yùn)行Porject,再次Debug時(shí)便可以看到變量的視圖會(huì)自動(dòng)變?yōu)?toString
方法的返回值,如下
這樣便能無需展開直接顯示 Goods
類的成員變量了,但該方式有幾個(gè)缺點(diǎn)
- 添加
Goods
的toString
方法之后需要重新運(yùn)行 - 如果
Goods
是被依賴的jar
這種已經(jīng)被編譯的只讀類,則無法更改 - 對(duì)于
Goods
中包含大量屬性(比如20+個(gè))的情況下,無法全部顯示完,所以就無法根據(jù)自己的需求決定查看具體哪些屬性值 自定義變量視圖
IDE提供給我們一種自定義變量視圖的方式,專門用來解決上面的問題并彌補(bǔ)了 toString
方法的不足。這里會(huì)有個(gè) 變量解析器
的概念,它用來控制當(dāng)前變量的顯示值(即debug時(shí)顯示在該變量后面的內(nèi)容,下稱”變量視圖”)。
首先Debug狀態(tài)下右擊變量,選擇 Customize Data Views
項(xiàng)
接下來在 Customize Data Views
彈窗的Tab中選擇 Java Type Renderers
項(xiàng),如下
點(diǎn)擊 +
來添加一個(gè)自定義的 變量解析器
自定義一個(gè) 變量解析器
,主要需要添加的是名稱、解析類型和解析方式三部分。
名稱:該解析器的標(biāo)識(shí)名稱
解析類型:表示當(dāng)前的解析器只對(duì)哪種類型的類進(jìn)行解析
解析方式:此處是核心部分,可以寫一個(gè)Java表達(dá)式,也可以寫一段代碼,這里的返回值就是該變量視圖
我們可以在IDE中添加多個(gè) 變量解析器
,通過控制它的開啟、禁用、順序、適用類等來控制當(dāng)前變量的顯示情況,下面進(jìn)行一次完整的操作流程演示
通過自定義 變量解析器
的好處是不需要重新運(yùn)行整個(gè)Project;而且還可以在Debug期間動(dòng)態(tài)切換變量視圖,比如
- 查看
name
屬性時(shí):"name: " + getName()
- 查看
type
屬性時(shí):"type: " + getType()
- 查看
title
屬性時(shí):"title: " + getTitle()
- ……
再進(jìn)一步抽象
看了官網(wǎng)的自定義Debug變量視圖這部分介紹后,感覺著實(shí)對(duì)于Debug很實(shí)用,通過自實(shí)現(xiàn)的方式使得開發(fā)者能夠動(dòng)態(tài)化控制變量視圖。
自定義 變量解析器
的方式已經(jīng)能夠解決開篇提到的問題,但我更希望能通過它來找到控制變量視圖的通法,即寫一個(gè)通用的 變量解析器
而不是每debug一種類型的變量就單獨(dú)添加一個(gè)解析器。接下來要做的事情很清楚了,就是添加一個(gè)能夠?qū)?duì)象實(shí)例序列化成字符串的方法即可。最先想到的是通過Json進(jìn)行轉(zhuǎn)化,但Json一般依賴三方包,而我們想讓Debug功能能夠跟IDE是統(tǒng)一基準(zhǔn)線的,所以盡可能選擇使用Jdk自帶的api。
于是考慮到了反射,對(duì)于一般通用的變量視圖,我們可以直接通過反射取到每個(gè)屬性名,然后結(jié)合當(dāng)前實(shí)例來獲取屬性值,直接在上面的 解析類型
中指定為 java.lang.Object
以支持所有類型變量的解析, 解析方式
中添加下面的代碼
if (((Object) this) instanceof String || ((Object) this) instanceof Number || ((Object) this) instanceof Class) { return ((Object) this); } StringBuilder sb = new StringBuilder("{"); Class<?> cls = ((Object) this).getClass(); java.lang.reflect.Field[] fields = cls.getDeclaredFields(); if (fields != null) { int size = fields.length; for (java.lang.reflect.Field field : fields) { field.setAccessible(true); Object value = field.get((Object) this); sb.append(field.getName()) .append("=") .append(String.valueOf(value)); if (--size > 0) { sb.append(", "); } } } return sb.append("}").toString();
添加完畢之后,會(huì)發(fā)現(xiàn)此時(shí)我們的IDE在Debug時(shí)異常強(qiáng)大,所有類型的變量視圖均自動(dòng)轉(zhuǎn)化成 key-value
形式的字符串,再也不用為了Debug變量而重寫 toString
方法。看下Debug的效果
這里的 User
和 Goods
類均沒有重寫 toString
方法,但都能通過上面添加的通用解析器來進(jìn)行變量視圖解析。
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android自定義View新年煙花、祝福語橫幅動(dòng)畫
這篇文章主要為大家詳細(xì)介紹了Android自定義View新年煙花、祝福語橫幅動(dòng)畫,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-01-01Android使用MediaPlayer和TextureView實(shí)現(xiàn)視頻無縫切換
這篇文章主要為大家詳細(xì)介紹了Android使用MediaPlayer和TextureView實(shí)現(xiàn)視頻無縫切換,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-10-10Android藍(lán)牙通信聊天實(shí)現(xiàn)發(fā)送和接受功能
這篇文章主要為大家詳細(xì)介紹了Android藍(lán)牙通信聊天實(shí)現(xiàn)發(fā)送和接受功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-07-07Spi機(jī)制在Android開發(fā)的應(yīng)用示例詳解
這篇文章主要為大家介紹了Spi機(jī)制在Android開發(fā)的應(yīng)用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08Android SurfaceView與TextureView使用方法詳細(xì)講解
SurfaceView和TextureView都繼承View,與普通的View不同的是,它倆可以在獨(dú)立線程中繪制渲染,性能更高,所以常被應(yīng)用在對(duì)繪制速率要求比較高的場(chǎng)景,比如相機(jī)預(yù)覽,視頻播放等等2022-10-10Android自定義控件實(shí)現(xiàn)雷達(dá)圖效果
這篇文章主要為大家詳細(xì)介紹了Android自定義控件實(shí)現(xiàn)雷達(dá)圖效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-09-09Android Kotlin環(huán)境使用ButterKnife的方法
本篇文章主要介紹了Android Kotlin環(huán)境使用ButterKnife的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-03-03