轉(zhuǎn)自:https://www.cnblogs.com/jack-1900/p/3883718.html
AndroidAnnotations是一個(gè)開(kāi)源框架,旨在加快Android開(kāi)發(fā)的效率。通過(guò)使用它開(kāi)放出來(lái)的注解api,你幾乎可以使用在任何地方, 大大的減少了無(wú)關(guān)痛癢的代碼量,讓開(kāi)發(fā)者能夠抽身其外,有足夠的時(shí)間精力關(guān)注在真正的業(yè)務(wù)邏輯上面。而且通過(guò)簡(jiǎn)潔你的代碼,也提高了代碼的穩(wěn)定性和后期的維護(hù)成本。以下AndroidAnnotations簡(jiǎn)稱為AA
可能會(huì)有人提出異議了,我們移動(dòng)設(shè)備的性能,不比后臺(tái)服務(wù)器擁有充足的內(nèi)存和運(yùn)算能力。當(dāng)大量的使用注解的時(shí)候,會(huì)不會(huì)對(duì)APP的造成什么不良的影響,會(huì)不會(huì)影響到APP的執(zhí)行性能?在這里先明確的聲明,AA不會(huì)給APP帶來(lái)任何副作用,相反它強(qiáng)大易用的api能為你帶來(lái)前所未有的編程體驗(yàn)。
目前主流的注解框架有xUtils、ButterKnife、Dragger和Roboguice,它們的實(shí)現(xiàn)原理都是一致的,都是通過(guò)反射機(jī)制實(shí)現(xiàn)的。通過(guò)在Runtime運(yùn)行期去反射類中帶有注解的Field和Method,然后再去執(zhí)行注解相對(duì)應(yīng)的邏輯代碼。大家都知道反射機(jī)制是在APP的運(yùn)行期執(zhí)行的,會(huì)造成執(zhí)行的效率下降,執(zhí)行時(shí)間變長(zhǎng)的缺點(diǎn)。當(dāng)在我們APP中大量的使用基于反射的注解,會(huì)嚴(yán)重影響到性能。但是AA的實(shí)現(xiàn)的邏輯并不是基于此。
AA工作的原理其實(shí)也很簡(jiǎn)單,它通過(guò)使用jdk 1.6引入的Java Annotation Processing Tool,
在編譯器中加了一層額外的自動(dòng)編譯步驟,用來(lái)生成基于你源碼的代碼。生成的代碼是你源碼的直接子類,而且自動(dòng)生成的類的名稱就是父類名稱后面加個(gè)下劃線。比如使用了@EActivity注解的MyActivity,AA都會(huì)自動(dòng)幫你生成一個(gè)名為MyActivity_的類。使用AA的注解在編譯期間就已經(jīng)自動(dòng)生成了對(duì)應(yīng)的子類,運(yùn)行期運(yùn)行的其實(shí)就是這個(gè)子類,所以說(shuō)AA的使用不會(huì)給APP的執(zhí)行性能造成負(fù)面影響。
AA開(kāi)發(fā)環(huán)境搭建:右鍵=>Properties=>Java Compiler => Annotation Processing => Factory Path。
下面我們通過(guò)示例來(lái)簡(jiǎn)單了解這個(gè)強(qiáng)大的框架,主要介紹一些常用的注解。
一、組件的注解
@EActivity這個(gè)注解是用來(lái)修飾Activity的,向Activity注入布局,也可以設(shè)置頁(yè)面的樣式為全屏、無(wú)Title。這些使用具有實(shí)意的注解來(lái)實(shí)現(xiàn),是不是很方便呀。對(duì)于其他的組件支持也是相當(dāng)簡(jiǎn)單的,如@EService、@EReceiver、@EProvider、@EApplication、@EApplication、@EFragment。同時(shí)也能修飾自定義控件,注解為@EView、@EViewGroup。支持是不是相當(dāng)全面。
二、資源引用的注解
有了AA,各種讓人煩躁的findViewById從此一去不再返了,你可以簡(jiǎn)單的使用@ViewById去綁定布局里面的控件,如果你的變量名和控件的id值一致,連id的指向也可省去。而且在注解中不寫(xiě)id的情況下,如果編譯器在R文件中找不到對(duì)應(yīng)變量id名的時(shí)候,編譯器也會(huì)給你提示,很是友好。
同時(shí)你要是想在成員變量中引用資源的話,只要在變量上加入對(duì)應(yīng)的注解修飾就可以了,同樣的如果變量名稱和資源id一致的時(shí)候,id就可省去。支持所有的資源文件,所有的。
如果你想獲取系統(tǒng)服務(wù),只要在你的變量前加上@SystemService注解。
獲取Intent中傳遞的值,加上@Extra注解,同時(shí)容錯(cuò)性很好,如果接收不到這個(gè)key對(duì)應(yīng)的value,也沒(méi)問(wèn)題,你可以設(shè)置默認(rèn)值。再有就是強(qiáng)轉(zhuǎn)失敗也不會(huì)造成crash,比如傳遞的是個(gè)int值,接收的時(shí)候是個(gè)String,也沒(méi)有問(wèn)題,只是接收失敗罷了。
很強(qiáng)大有木有,修飾成員變量的注解主要用來(lái)解決它們初始化的問(wèn)題,做到聲明即初始化,拿來(lái)即可用的功能。還有很多屬性,就不一一介紹了。
三、事件綁定注解
AA支持基本所有的原生事件的綁定,示例中展示的是常見(jiàn)的三種。簡(jiǎn)單的一個(gè)事件注解加上一個(gè)監(jiān)聽(tīng)的控件id,就能完成以前要做的復(fù)雜的事件綁定呀,內(nèi)部類實(shí)現(xiàn)呀等。而且方法名可以任意定制,如果方法名與控件的id一致,注解中的id也可省去,同樣如果匹配不上的話,編譯器也編譯不過(guò)的。方法的參數(shù)列表也是可以自定義的,當(dāng)需要參數(shù)的時(shí)候,就把原生監(jiān)聽(tīng)方法的參數(shù)列表拉過(guò)來(lái)就可以直接使用了。其他常用的還有@TextChange、@ItemClick、@SeekBarProgressChange。
四、異步線程與UI線程的交互
當(dāng)View相關(guān)的成員變量初始化完畢后,會(huì)調(diào)用擁有@AfterViews注解的方法,你可以在里面初始化一些界面控件等。如果其他的成員變量處事完畢,就會(huì)調(diào)用@AfterInject。
比如大多數(shù)應(yīng)用的邏輯是這樣的,初始化界面之后,就發(fā)起耗時(shí)的數(shù)據(jù)請(qǐng)求,然后解析獲取到的數(shù)據(jù),再設(shè)置到界面上。一般的涉及UI線程與異步任務(wù)交互的時(shí)候,相對(duì)都比較麻煩一些。讓我們看下AA是如何實(shí)現(xiàn)的。
很簡(jiǎn)單吧,UI線程執(zhí)行的方法加個(gè)@UiThread,異步線程方法加個(gè)@Background,兩者的交互就是方法直接的相互調(diào)用,其他的你不用關(guān)心,一切的實(shí)現(xiàn)都是AA的編譯器去自動(dòng)生成交互的代碼。交互的過(guò)程,完全沒(méi)有在執(zhí)行異步的感覺(jué),不用再使用Handler去發(fā)送接收Message了。兩個(gè)注解就把以前一堆的代碼實(shí)現(xiàn)的功能給實(shí)現(xiàn)了,真心給個(gè)最大的贊。
五、Rest API
在AA中也支持Rest API,而且支持所有的HTTP請(qǐng)求方法。下面演示的是一個(gè)GET請(qǐng)求。
定義一個(gè)請(qǐng)求的接口,然后就可以直接使用了,不需要自己再去實(shí)現(xiàn)。這個(gè)跟公司后臺(tái)接口設(shè)計(jì)緊密相關(guān),如果你公司接口交互都是Rest風(fēng)格的話,你就重寫(xiě)下,好好體驗(yàn)AA的魅力吧。
寫(xiě)在最后:AndroidAnnotations功能強(qiáng)大,是注解框架中當(dāng)之無(wú)愧的王者,靈活的API大大的提高了開(kāi)發(fā)的效率,降低維護(hù)的成本。如果說(shuō)它有什么弊端,我只能說(shuō)NO,它沒(méi)有弊端。如果硬要來(lái)一個(gè)的話,也只能是它的注解比較多,熟悉需要一段時(shí)間,如果整個(gè)開(kāi)發(fā)團(tuán)隊(duì)技術(shù)遷移過(guò)來(lái)的話,前期技術(shù)成本稍高。但是所謂砍柴不誤磨刀功,還是不能歸結(jié)為一個(gè)弊端。AA還有很多強(qiáng)大實(shí)用的功能,限于篇幅就不展開(kāi)說(shuō)了,自己去探索吧。
好了,今天的干貨都到此為止。