一验辞、注解
1稿黄、元注解
簡(jiǎn)單描述:是由Java提供的基礎(chǔ)注解,負(fù)責(zé)注解其它注解
2跌造、元注解有
@Target? -----------> 注解對(duì)象的范圍
@Retention --------> 注解保留的生命周期
@Inherited ---------> 標(biāo)明所修飾的注解在所作用的類上杆怕,是否可以被繼承
@Documented ---->? javadoc的工具文檔化,一般不關(guān)心
3鼻听、常用注解解釋
二财著、自定義注解
1、自定義注解規(guī)則:
其中:@Target 和 @Retention 這兩個(gè)就是上面講的元注解撑碴,(上面定義也說(shuō)了撑教,負(fù)責(zé)注解其他注解。)醉拓,value 就是在你使用自定義注解的時(shí)候需要填寫的內(nèi)容 如:@BindView( 這里就是需要填寫的int 類型的值 )
使用:
kotlin 自定義注解如下:
kotlin 自定義注解的使用伟姐,同上java的注解一樣。
三亿卤、自定義注解的應(yīng)用 (APT 技術(shù))
上面自定義注解大家應(yīng)該都知道如何去創(chuàng)建和使用了愤兵,但是使用之后如何去處理和解析自定義注解才是關(guān)鍵。下面講通過(guò)一個(gè)案例講解如何去使用并解析排吴,注解能做到哪些事情秆乳。
項(xiàng)目主要的內(nèi)容和背景:模仿ButterKnife,通過(guò)注解去實(shí)現(xiàn)findviewById 的操作。
項(xiàng)目前期準(zhǔn)備工作钻哩,三步走:
1屹堰、創(chuàng)建model ,這里主要?jiǎng)?chuàng)建兩個(gè)model,一個(gè)是專門放注解的 annotations ,一個(gè)是用來(lái)解析注解的annotation_compiler
2、在annotation_compiler 中添加AutoService的注解街氢,為了幫助我們對(duì)注解進(jìn)行處理:
3扯键、添加相互的依賴
首先:annotation_compiler 項(xiàng)目是對(duì)annotation中注解的內(nèi)容進(jìn)行解析,所以珊肃,annotation_compiler中需要添加對(duì)annotation的依賴荣刑,所以需要在annotation_compiler項(xiàng)目gradle中添加:
同時(shí)項(xiàng)目中需要使用到注解,因?yàn)槲覀儗懙倪@個(gè)注解也是為了提供給項(xiàng)目(app)伦乔,進(jìn)行使用的厉亏,所以項(xiàng)目中我們要添加對(duì)annotation_compiler和annotation 的依賴。所以這里在app中的gradle中添加如下代碼:
正式的項(xiàng)目開(kāi)始:
首先我們需要了解到叶堆,注解的解析發(fā)生在 java---->javac 編譯過(guò)程中去實(shí)現(xiàn)的,而后面我們要講到的插樁技術(shù)是發(fā)上在 javac---->dex 之間的斥杜。所以注解實(shí)際上是對(duì)注解所標(biāo)記的內(nèi)容進(jìn)行處理虱颗,并生成對(duì)應(yīng)的 .java 文件沥匈。
下面開(kāi)始進(jìn)入正題:
在annotation 中編寫注解
在annotation_compiler 編寫對(duì)應(yīng)的解析類,并生成處理被標(biāo)記的屬性的方法忘渔。
思路:因?yàn)槲覀兿胍龅氖莊indviewById, 所以我們首先要確定我們的注解注解了哪些view,同時(shí)需要生成一個(gè)文件高帖,而這個(gè)文件做的事情就是 對(duì)所有被標(biāo)記的view,進(jìn)行findViewById.
在annotation_compiler 中創(chuàng)建一個(gè)類,這里就叫:AnnotationCompiler 繼承自?AbstractProcessor
初始化等會(huì)生成文件需要用到的類散址,同時(shí)實(shí)現(xiàn)兩個(gè)父類的方法,如下
注意:當(dāng)java在編譯的時(shí)候宣赔,會(huì)自動(dòng)執(zhí)行 process 中的方法预麸,并將被注解的元素和方法,回傳到這里儒将,所以后面我們就是在這個(gè)父類的方法下面對(duì)應(yīng)的去解析被標(biāo)注的view.
這里要注意一定要記得關(guān)流吏祸,一定要記得關(guān)流,一定要記得關(guān)流
這里來(lái)看下我們生成的文件是什么樣子的:
在app中钩蚊,我們對(duì)應(yīng)的編寫一個(gè)類贡翘,一個(gè)是接口,接口是為了綁定講對(duì)應(yīng)的view 傳遞到生成的類中去的砰逻,上面也看到了鸣驱,我們生成的類實(shí)現(xiàn)了一個(gè)接口叫:IBinder,? 為什么要這樣蝠咆,因?yàn)槟銜?huì)看到其實(shí)findviewById踊东,前面是有一個(gè)view的,真正的findViewById 應(yīng)該是 view.findViewById.
編寫一個(gè)用來(lái)綁定的幫助類如下
在activity 中如何去使用:
總結(jié):在不知道我們要生成什么文件的時(shí)候刚操,我們可以先用java實(shí)現(xiàn)我們的功能递胧,再講這些重復(fù)的功能通過(guò)注解去生成文件在進(jìn)行統(tǒng)一處理,這樣就可以知道我們?cè)谏晌募臅r(shí)候赡茸,如何去對(duì)應(yīng)的去寫每一行代碼了。
注意:
1祝闻、把工程的gradle-wrapper和gradle-plugin分別降低到4.10.1占卧,3.2.0原因:gradle - 3.3 - 3.4 中 javaCompileTask 沒(méi)有處理 Annotation Processer
2、有些無(wú)法生成對(duì)應(yīng)的文件联喘,這里需要我們創(chuàng)建如下文件夾以及文件华蜒,切記要一模一樣。
文件夾:resources\META-INF\services
文件:javax.annotation.processing.Processor
內(nèi)容:為你編寫的AnnotationCompiler全路徑豁遭,這里我的文件全路徑為:com.example.annotation_compiler.AnnotationCompiler