Android-逆向分析ButterKnife框架

好了,言歸正傳。

這一篇文章,我們不談ButterKnife的基本使用,只談如何通過(guò)JavaSe的技術(shù),思考并分析ButterKnife這一Android開(kāi)發(fā)界內(nèi)排行前十的注解框架。

唯物主義辯證法認(rèn)為,世界上一切事物都是具有普遍的聯(lián)系我們首先從ButterKnife的使用步驟開(kāi)始,倒推分析該框架使用了什么樣的技術(shù),然后自己寫一個(gè)簡(jiǎn)單的ButterKnife小框架。

在正式寫這篇博客之前,需要對(duì)反射以及注解(JavaSe技術(shù))有一個(gè)初步的認(rèn)識(shí),就算不了解的也沒(méi)有關(guān)系,筆者也提供了兩篇博客供大家學(xué)習(xí)參考,點(diǎn)擊這里了解反射,點(diǎn)擊這里了解注解?,(這兩篇也是筆者一字一字碼出來(lái)的,望各位大兄弟不吝star)只需要花個(gè)十多分鐘認(rèn)真細(xì)心的看,反射和注解都不是很大的問(wèn)題。接下來(lái)的東西還是很需要這兩篇博客中使用到的基礎(chǔ)。

說(shuō)起B(yǎng)utterKnife(黃油刀),大家肯定會(huì)想到,哇,這個(gè)是用來(lái)簡(jiǎn)化findViewById以及快速實(shí)現(xiàn)點(diǎn)擊事件等等一個(gè)深受大家好評(píng)的框架、沒(méi)錯(cuò),下圖就是大家熟悉的寫法


butterKnife常用寫法

熟悉注解的同學(xué),可能一眼就看出,咦,這個(gè)@BindView以及@OnClick不就是兩個(gè)注解嗎?沒(méi)錯(cuò),的確是,而且,這個(gè)注解的類型是int值,因?yàn)槔锩媸蔷唧w的View ID。了解這種情況后,就有了如下代碼:首先,我們先寫找控件的注解


自定義控件注解

步驟1:

在使用ButterKnife注解之前,我們需要bind(Activty),

所以,我們就按照那種寫法,先聲明一個(gè)ButterKnife類,里面有個(gè)bind方法,參數(shù)是Activty

步驟2:

A:既然從外部傳入了這個(gè)Activity,那么,我們就可以通過(guò)暴力反射獲取該Activity上所有的成員變量,這里返回的是字段數(shù)組,

B:(因?yàn)槭菙?shù)組,所以需通過(guò)迭代器遍歷獲取每一個(gè)字段) 拿到成員變量之后,繼續(xù)通過(guò)暴力反射其變量上的自定義注解 ?就 ?可以獲取注解上的值(核心邏輯)

C:接著,我們既然通過(guò)B步驟已經(jīng)獲取到注解上的值(也就是控件的ID),那么就可以通過(guò)findViewByid去獲取具體的View控件

D:最后,在通過(guò)反射將C步驟獲取到的控件, 將其控件賦值給變量


步驟1


步驟2:模仿bindView邏輯


最后,為了測(cè)試這種寫法能否達(dá)到預(yù)期的效果,我寫了一個(gè)Demo,經(jīng)測(cè)試,效果如圖:


測(cè)試用到的Xml
沒(méi)有findViewById依舊可以獲取到屬性值

經(jīng)測(cè)試,myTextViewOne,myTextViewTwo這兩個(gè)控件,我沒(méi)有findViewById, 依舊可以獲取到TextView上的值,所以,這個(gè)小功能經(jīng)測(cè)試是可行的,

類似的,還有一個(gè)自定義注解點(diǎn)擊事件,

依舊可以按照上面的寫法,先寫一個(gè)OnClick的自定義注解,如下圖


自定義點(diǎn)擊事件注解

這里需要注意的是,

我們的點(diǎn)擊事件的邏輯,是寫在方法上的,所以,需要定義注解的使用范圍是在方法上 也就是 @Target(ElementType.METHOD)

接下來(lái)的步驟,和上面的bindview 步驟差不多,

(暴力反射---獲取注解的值----通過(guò)該值找到控件---對(duì)控件進(jìn)行點(diǎn)擊監(jiān)聽(tīng)---反射調(diào)用使用了注解的方法),

這里直接上圖


自定義點(diǎn)擊注解

接下來(lái),我們寫代碼測(cè)試該注解:


測(cè)試點(diǎn)擊注解

經(jīng)測(cè)試,這個(gè)功能是完全可以使用的,

這樣,一個(gè)簡(jiǎn)單而不簡(jiǎn)約的迷你型ButterKnife框架就寫好了。

最后總結(jié):

1:自定義注解綁定的是具體的控件,也就是int值,根據(jù)自定義注解去定義這個(gè)int屬性值

2:在使用了該自定義注解后的控件,通過(guò)暴力反射獲取字段在根據(jù)其字段拿到具體的注解屬性值

3:根據(jù)拿到具體的屬性值,在做進(jìn)一步的操作

4:當(dāng)然,要是做到真正的ButterKnife框架還是有一些差距。但是我們這里只做簡(jiǎn)單的技術(shù)分析

最后,千里之行、始于足下,加油!

源碼,(直接看圖就可以了吧)附github地址

項(xiàng)目地址

如果這篇文章對(duì)您有開(kāi)發(fā)or學(xué)習(xí)上的些許幫助,希望各位看官留下寶貴的star,謝謝。

Ps:著作權(quán)歸作者所有,轉(zhuǎn)載請(qǐng)注明作者, 商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處(開(kāi)頭或結(jié)尾請(qǐng)?zhí)砑愚D(zhuǎn)載出處,添加原文url地址),文章請(qǐng)勿濫用,也希望大家尊重筆者的勞動(dòng)成果,謝謝。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,810評(píng)論 25 709
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,506評(píng)論 19 139
  • 前言:ButterKnife是一個(gè)專注于Android系統(tǒng)的View注入框架,以前總是要寫很多findViewBy...
    Donkor閱讀 10,477評(píng)論 3 23
  • 哀公問(wèn)於孔子曰:「寡人欲論魯國(guó)之士,與之為治,敢問(wèn)如何取之?」孔子對(duì)曰:「生今之世,志古之道,居今之俗,服古之服,...
    百無(wú)一用知止閱讀 328評(píng)論 0 1
  • 最近有朋友得了膽結(jié)石,看著他疼的連走路都困難,據(jù)他描述絞痛的想死的心都有了,而患膽結(jié)石的原因是十多年不吃早餐...
    彤話Ashley閱讀 630評(píng)論 0 1

友情鏈接更多精彩內(nèi)容