以下內(nèi)容主要講解EventBus帝美、Retrofit、Dagger2哼丈、ButterKnife等流行第三方庫(kù)都在使用的AnnotationProcessor技術(shù).
一 AnnotationProcessor工作流程
通過解析在源碼中使用注解標(biāo)記的類/變量/方法,生成所需的工具類,以擺脫繁瑣重復(fù)的手工代碼.
注解(也被成為元數(shù)據(jù))為我們?cè)诖a中添加信息提供了一種形式化的方法关串,使我們可以在稍后某個(gè)時(shí)刻非常方便地使用這些數(shù)據(jù)平匈。
用于標(biāo)注注解的注解叫做元注解,用于描述注解的使用范圍,生命周期,繼承關(guān)系等.
二 注解通常在項(xiàng)目中有兩種用處
- 運(yùn)行時(shí)注解. 在程序運(yùn)行時(shí),通過反射機(jī)制拿到注解相關(guān)信息進(jìn)行相關(guān)操作,效率不高.
- 編譯時(shí)注解.在程序編輯階段,通過注解獲取相關(guān)信息,生成相應(yīng)的工具代碼.不影響運(yùn)行時(shí)的效率.
三 項(xiàng)目為什么要使用APT
為了滿足項(xiàng)目在不同場(chǎng)景中的需求,目前主要滿足兩個(gè):
- 事件綁定與解綁.
原先事件通信是通過RxJava2,但是每次事件綁定和解綁都要手動(dòng)操作,所以使用注解完成. - 頁(yè)面信息攜帶.
最近兩周的工作主要是使用注解完成頁(yè)面跳轉(zhuǎn)時(shí)信息的傳遞與解析.
借鑒Dart和ARouter項(xiàng)目,重復(fù)造輪子的原因是:
a. 需要默認(rèn)傳遞一些頁(yè)面信息.
b. 不能滿足頁(yè)面返回信息的打包及解析.
c. 自己寫有利于拓展.
未來考慮實(shí)現(xiàn)h5與native的跳轉(zhuǎn).
四 技巧
- 運(yùn)行時(shí)注解的解析器只能是Java-library.但是可以使用android相關(guān)的api.
- auto-service第三方庫(kù)可自動(dòng)生成Processor配置
- java-poet可通過Builder模式輔助生成Java文件.
MethodSpec 代表一個(gè)構(gòu)造函數(shù)或方法聲明。
TypeSpec 代表一個(gè)類牍氛,接口晨继,或者枚舉聲明。
FieldSpec 代表一個(gè)成員變量搬俊,一個(gè)字段聲明紊扬。
JavaFile包含一個(gè)頂級(jí)類的Java文件蜒茄。
在編寫解析器時(shí),主要用到以下三個(gè)工具類:
private Filer filer; //文件相關(guān)的輔助類
private Elements elementUtils; //元素相關(guān)的輔助類
private Messager messager; //日志相關(guān)的輔助類
最重要的是Element元素,相當(dāng)于 XML 中的 DOM 樹珠月,可以通過一個(gè)元素去訪問它的父元素或者子元素扩淀。感想
APT不是特別高深的技術(shù),它提供了一種在編譯時(shí)解析注解并生成模版工具類的開發(fā)方式,挺異想天開,讓人稱奇的:)