拓展篇:注解處理器最佳實(shí)踐

基礎(chǔ)篇中买决,我們介紹了什么是注解以及如何開發(fā)注解處理器讥珍,今天就來(lái)說(shuō)說(shuō)在開發(fā)編譯時(shí)注解處理器中的那些最佳實(shí)踐。

什么是Android-apt

我們知道APT是集成在javac當(dāng)中的工具灼卢,這個(gè)Android-apt又是什么鬼呢? 對(duì)于從事Android開發(fā)的同學(xué)來(lái)說(shuō)练对,ButterKnife這個(gè)開源工具可是非常熟悉。在使用該工具之前吹害,你需要進(jìn)行配置:

compile 'com.jakewharton:butterknife:8.4.0'
apt 'com.jakewharton:butterknife-compiler:8.4.0'

這里的有什么用螟凭?我們?cè)谏弦还?jié)中沒(méi)有配置apt插件照樣可以用,這是怎么一回事它呀?
Anroid-apt是用在Android Studio中處理注解處理的插件螺男。它有兩方面的作用:

  1. 只允許配置編譯時(shí)注解處理器依賴,但在最終APK或者Library中不包含注解處理器的代碼纵穿。
  2. 設(shè)置源路徑下隧,以便由注解處理器生成的代碼能被Android Studio識(shí)別。

另外政恍,一些注解處理器可以接受外部的參數(shù)汪拥,在IDEA當(dāng)中我們可以直接配置,但是基于IDEA而來(lái)的Android Studio反而無(wú)法直接配置篙耗,借助Android-apt插件我們可以實(shí)現(xiàn)該功能迫筑,其用法如下:

apt{
    arguments{
        配置參數(shù)名稱 參數(shù)值
    }

}

對(duì)與在一個(gè)jar包中的注解處理器(API和處理器)而言,我們不需要進(jìn)行特殊的配置宗弯,它照樣可以工作脯燃。如果我們需要在項(xiàng)目當(dāng)中引用注解處理器生成的代碼,那么就需要使用Android-apt插件來(lái)幫助解決蒙保。

對(duì)于Butter Knife辕棚,EventBus 3.0這類工具,最終我們都需要在自己項(xiàng)目引用注解處理器生成的代碼邓厕,因此需要為其配置Android-apt逝嚎。EventBus 3.0的注解處理器還接受兩個(gè)參數(shù),當(dāng)然也要借助Android-apt插件了,以EventBus在工程的配置為例:


這里寫圖片描述

到現(xiàn)在详恼,我們恍然大霧补君,原來(lái)Android-apt是這么用的啊。知其然更知其所以然啊昧互,現(xiàn)在無(wú)論你遇到什么樣的配置問(wèn)題挽铁,那都是小菜一碟。

你正在為自己明白了Android-apt的用途的時(shí)候敞掘,無(wú)意間聽到了消息:android-apt插件作者近期已經(jīng)發(fā)表聲明表示后續(xù)不會(huì)再繼續(xù)維護(hù)該插件叽掘。

噩耗就是來(lái)的這么隨心所欲啊>裂恪8狻!好不容易懂了,結(jié)果發(fā)現(xiàn)這玩意不再更新疯潭,這是什么梗什么怨啊赊堪。


這里寫圖片描述

什么是annotationProcessor

Gradle從2.2版本開始支持annotationProcessor功能來(lái)代替Android-apt面殖。另外竖哩,和android-apt只支持javac編譯器相比,annotationProcessor同時(shí)支持javac和jack編譯器脊僚。

和Android-apt使用相比相叁,annotationProcessor使用更為簡(jiǎn)單,還是以EventBus的配置為例:


這里寫圖片描述

不難看出辽幌,使用annotationProcessor更為簡(jiǎn)單增淹。如果你現(xiàn)在的Gradle版本是2.2.X以上,可以考慮替換掉Android-apt了乌企。


如何劃分項(xiàng)目結(jié)構(gòu)

由于編譯時(shí)注解處理器只在編譯過(guò)程中使用虑润,因此我們不希望注解處理器相關(guān)的代碼在最終的APK中存在,這樣能夠有效的較少方法數(shù)加酵。比如我通常在編寫注解Annotation Processor的時(shí)候會(huì)引用javapoet和Guava拳喻,如果將這些代碼也打進(jìn)最終的APK中會(huì)造成方法數(shù)的暴增,因此建議將注解處理器相關(guān)代碼單獨(dú)成為一個(gè)模塊猪腕。

另外為了方面注解被其他工程引用冗澈,通常我也建議將注解的定義單獨(dú)劃分成一個(gè)模塊。

綜上陋葡,我們最終的項(xiàng)目結(jié)構(gòu)如下:

  • xxx/xxx-api:主工程/提供api亚亲,Android Library類型
  • xxx-compiler:注解處理器模塊,Java Library類型
  • xxx-annotations:自定義注解腐缤,Java Library類型

xxx/xxx-api依賴xxx-annotations,xxx-compiler依賴xxx-annotations捌归。這點(diǎn)Butter Knife給我們一個(gè)非常好的示范:

這里寫圖片描述


替換jar為moudle依賴

基礎(chǔ)篇中我們說(shuō)道,最終要講注解處理器打成jar包岭粤。這樣太麻煩了惜索,總不能每次修改都要重新打個(gè)jar包吧,然后拷貝吧?

其實(shí)在Android Studio當(dāng)中我們同樣可以采用moudle依賴的形式绍在,這和我們以前依賴其他模塊并沒(méi)有太大的區(qū)別门扇,比如我們?cè)谛枰⒔馓幚砥鞯牡胤揭蕾嘺pt即可:

compile project(":apt")

但要在注解處理器moudle中的build.gradle文件中,配置:

sourceCompatibility = "1.7"
targetCompatibility = "1.7"
 

但是這樣我們的注解處理器就會(huì)被打包到apk當(dāng)中偿渡,現(xiàn)在就可以利用上面說(shuō)的Android-apt了臼寄。


使用@AutoService注解簡(jiǎn)化配置

基礎(chǔ)篇中,我們說(shuō)道需要注冊(cè)處理器溜宽,雖然沒(méi)什么難度吉拳,但是弄不好一個(gè)粗心就寫錯(cuò)了,有沒(méi)有什么更好的方式呢适揉?

剛寫Google為我們提供的@AutoService留攒,該注解可以方便的生成 META-INF/services/中注解的配置信息煤惩。

首先需要添加依賴:

compile 'com.google.auto.service:auto-service:1.0-rc2'

接起來(lái)在你的注解處理器類上使用@AutoService注解即可,如:


@AutoService(PrintProcessor.class)
public class PrintProcessor extends AbstractProcessor {

    //...省略相關(guān)代碼
}

使用非常簡(jiǎn)單不是么炼邀,無(wú)需再關(guān)注 META-INF/services/的創(chuàng)建以注解處理器的注冊(cè)了魄揉,簡(jiǎn)直棒呆了。關(guān)于該注解更多的信息請(qǐng)查看github:https://github.com/google/auto/tree/master/service


如何調(diào)試注解處理器

對(duì)于編譯時(shí)注解處理器的調(diào)試顯得略微麻煩些拭宁,不同構(gòu)建方式(Maven洛退,Ant,Gradle等)會(huì)稍微有些區(qū)別杰标,但也只是形勢(shì)上的區(qū)別兵怯,本質(zhì)上還是離不開JPDA。

編譯時(shí)注解處理器是運(yùn)行在一個(gè)單獨(dú)的JVM當(dāng)中腔剂,因此我們想要對(duì)它進(jìn)行調(diào)試可以使用Remote Debug媒区。無(wú)論是是Eclipse中還是,IDEA當(dāng)中掸犬,對(duì)Remote Debug功能都提供了良好的支持袜漩,作為IDEA二次開發(fā)出的Android Studio同樣也不例外。先來(lái)看一下如何開啟JVM的遠(yuǎn)程調(diào)試功能登渣,在啟動(dòng)JVM的時(shí)候加上以下參數(shù)即可:

//jdk 1.5以前寫法噪服,當(dāng)然該命令是先后兼容的
-J-Xdebug -J-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005

//jdk 1.5及以后版本寫法
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005

這些參數(shù)的含義這里不錯(cuò)細(xì)說(shuō),你唯一要做的就是修改address指定一個(gè)端口號(hào)∈ぜ耄現(xiàn)在我們以Android Studio中調(diào)試注解處理器為例粘优。

首先在gradle.properties中配置一下參數(shù):

org.gradle.daemon=true
org.gradle.jvmargs=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005

接下來(lái)在控制臺(tái)當(dāng)中使用gradle --daemon命令來(lái)啟動(dòng)守護(hù)線程.

到現(xiàn)在為止在注解處理器工程中的配置已經(jīng)完成了。

接下來(lái)就需要在Android Studio中建立Remote Debugger呻顽,操作步驟如下:


這里寫圖片描述

這里的端口號(hào)要保持一致雹顺,不然Remote Debugger是連不上gradle的守護(hù)線程的.設(shè)置完成后該Remote Debugger就可以成功的鏈接到deamon線程了.

準(zhǔn)備工作完成,下面就可以來(lái)調(diào)試了(別忘記加斷點(diǎn))廊遍。具體怎么做呢嬉愧?很簡(jiǎn)單,就是重新編譯即可喉前。這里為了方便演示,直接圖形化操作:


這里寫圖片描述

在構(gòu)建過(guò)程中,Remote Debugger將會(huì)觸發(fā)斷點(diǎn)并掛起構(gòu)建過(guò)程,接下來(lái)就可以像往常一樣調(diào)試了.

關(guān)于注解處理的調(diào)試就到這里没酣,其他工具大同小議,在這里就不做說(shuō)明了卵迂。


總結(jié)

有關(guān)注解開發(fā)裕便,調(diào)試方面的問(wèn)題我們已經(jīng)說(shuō)的差不多了。在這2016年的最后一天见咒,我們來(lái)年再見偿衰。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子下翎,更是在濱河造成了極大的恐慌缤言,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,464評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件视事,死亡現(xiàn)場(chǎng)離奇詭異胆萧,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)郑口,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,033評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門鸳碧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人犬性,你說(shuō)我怎么就攤上這事√诮觯” “怎么了乒裆?”我有些...
    開封第一講書人閱讀 169,078評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)推励。 經(jīng)常有香客問(wèn)我鹤耍,道長(zhǎng),這世上最難降的妖魔是什么验辞? 我笑而不...
    開封第一講書人閱讀 59,979評(píng)論 1 299
  • 正文 為了忘掉前任稿黄,我火速辦了婚禮,結(jié)果婚禮上跌造,老公的妹妹穿的比我還像新娘杆怕。我一直安慰自己,他們只是感情好壳贪,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,001評(píng)論 6 398
  • 文/花漫 我一把揭開白布陵珍。 她就那樣靜靜地躺著,像睡著了一般违施。 火紅的嫁衣襯著肌膚如雪互纯。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,584評(píng)論 1 312
  • 那天磕蒲,我揣著相機(jī)與錄音留潦,去河邊找鬼。 笑死辣往,一個(gè)胖子當(dāng)著我的面吹牛兔院,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播排吴,決...
    沈念sama閱讀 41,085評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼秆乳,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起屹堰,我...
    開封第一講書人閱讀 40,023評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤肛冶,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后扯键,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體睦袖,經(jīng)...
    沈念sama閱讀 46,555評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,626評(píng)論 3 342
  • 正文 我和宋清朗相戀三年荣刑,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了馅笙。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,769評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡厉亏,死狀恐怖董习,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情爱只,我是刑警寧澤皿淋,帶...
    沈念sama閱讀 36,439評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站恬试,受9級(jí)特大地震影響窝趣,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜训柴,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,115評(píng)論 3 335
  • 文/蒙蒙 一哑舒、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧幻馁,春花似錦洗鸵、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,601評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至儒将,卻和暖如春吏祸,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背钩蚊。 一陣腳步聲響...
    開封第一講書人閱讀 33,702評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工贡翘, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人砰逻。 一個(gè)月前我還...
    沈念sama閱讀 49,191評(píng)論 3 378
  • 正文 我出身青樓鸣驱,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親蝠咆。 傳聞我的和親對(duì)象是個(gè)殘疾皇子踊东,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,781評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,321評(píng)論 25 707
  • 編譯時(shí)注解處理 若希望對(duì)編譯時(shí)的注解進(jìn)行處理需要做 自定義類集成自AbstractProcessor 重寫其中的p...
    生活理當(dāng)如此閱讀 8,890評(píng)論 3 18
  • 前面寫了Android 開發(fā):由模塊化到組件化(一),很多小伙伴來(lái)問(wèn)怎么沒(méi)有Demo啊?之所以沒(méi)有立刻放demo的...
    涅槃1992閱讀 8,040評(píng)論 4 37
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,863評(píng)論 6 342
  • 文 | 二靜 圖 | 網(wǎng)絡(luò) 獨(dú)行煙柳路北滥, 月伴醉人歸。 忽逢瀟雨落闸翅, 夢(mèng)憶把春追再芋。 我是二靜,愿你在每個(gè)22:2...
    二靜不二閱讀 851評(píng)論 1 3