ButterKnife原始碼解析
ButterKnife(https://github.com/JakeWharton/butterknife)是一款android平臺的依賴注入框架,通過該工具可以實現View、OnClickListener的注入,省去了findViewById、setOnClickListener的過程。使用方法如下:
通過@BindView註解實現findViewById的功能,完成View注入;通過@OnClick完成OnClickListener點選事件的注入,給ID對應的View設定點選事件和響應函式。關於註解的定義和解析可以參照這篇文章:Java註解。ButterKnife使用的就是編譯時解析註解的技術,在編譯時對註解進行解析,生成中間檔案,在ButterKnife.bind時引用註解編譯器生成的中間檔案,完成依賴注入。
註解的定義
BindView註解定義中使用了元註解@Retention(CLASS)定義了該註解只保留到編譯期間,執行時會丟棄;@Target(FIELD)表示該註解只能用在成員變數上面。
OnClick註解中@Target(METHOD)表示該註解只能用於方法上;
ListenerClass是一個@Target(ANNOTATION_TYPE)型別的註解,表示ListenerClass只能用在註解上;且@Retention(RUNTIME)表示該註解可以保留到JVM中,也就是執行時能夠通過反射來獲取。
註解的解析
下面對@BindView和@OnClick兩種註解的解析進行講解。編譯時註解的解析:
編譯時 Annotation 指 @Retention 為 CLASS 的 Annotation,由編譯器自動解析。需要做的
a. 自定義類整合自 AbstractProcessor(編譯器在編譯時自動查詢所有繼承自 AbstractProcessor 的類,然後呼叫他們的 process 方法去處理)
b. 重寫其中的 process 函式
ButterKnife實現了ButterKnifeProcessor來進行編譯時註解的解析:
ButterKnifeProcessor.process()函式如下:
process函式先呼叫findAndParseTargets生成bindingMap,然後通過binding.brewJava老生成Java檔案。findAndParseTargets的實現如下(這裡只關注@BindView和@OnClick):
其中呼叫parseBindView對註解為@BindView的Field進行解析;findAndParseListener對@OnClick之類的Listener註解進行解析。parseBindView程式碼如下:
parseBindView的主要工作是建立了BindingSet.Builder。getOrCreateBindingBuilder()如下:
getOrCreateBindingBuilder內部呼叫了BindingSet.newBuilder。
newBuilder生成了Builder物件,Builder物件定義了生成的Java檔名、mView所屬物件的型別等。Builder物件生產後,parseBindView就根據@BindView註解資訊生成FieldViewBinding物件,之後呼叫了Builder.build()函式;@BindView的解析已經完成後,最後通過BindingSet.brewJava來生成中間檔案。@BindView在生成檔案對應瞭如下:
生成的中間檔案如下所示:
可以看到,中間檔案裡完成了對Target中成員變數的注入。
那麼中間檔案又是在什麼時候被呼叫的呢?答案就是ButterKnife.bind(this)
bind函式根據呼叫的類名查詢其對應的className_ViewBinding的類名,然後反射呼叫其建構函式。
至此,ButterKnife的@BindView的執行流程就是這樣。
相關文章
- 【原始碼解析】- ArrayList原始碼解析,絕對詳細原始碼
- Java Timer原始碼解析(定時器原始碼解析)Java原始碼定時器
- O3-開源框架使用之Butterknife 8.8.1及原始碼淺析框架原始碼
- ReactNative原始碼解析-初識原始碼React原始碼
- Hive原始碼解析Hive原始碼
- ArrayList原始碼解析原始碼
- ConcurrentHashMap原始碼解析HashMap原始碼
- LinkedBlockingQueue 原始碼解析BloC原始碼
- Axios原始碼解析iOS原始碼
- RecyclerView原始碼解析View原始碼
- MyBatis原始碼解析MyBatis原始碼
- CountDownLatch原始碼解析CountDownLatch原始碼
- Promise 原始碼解析Promise原始碼
- Mansonry原始碼解析原始碼
- Observer原始碼解析Server原始碼
- SparseArray 原始碼解析原始碼
- RateLimiter原始碼解析MIT原始碼
- AutoMapper原始碼解析APP原始碼
- ThreadLocal原始碼解析thread原始碼
- Koa 原始碼解析原始碼
- Koa原始碼解析原始碼
- RxPermission原始碼解析原始碼
- Express原始碼解析Express原始碼
- redux原始碼解析Redux原始碼
- CopyOnWriteArrayList原始碼解析原始碼
- LeakCanary原始碼解析原始碼
- ArrayBlockQueue原始碼解析BloC原始碼
- ReentrantLock原始碼解析ReentrantLock原始碼
- OKio原始碼解析原始碼
- ReentrantReadWriteLock原始碼解析原始碼
- CyclicBarrier原始碼解析原始碼
- Semaphore原始碼解析原始碼
- Exchanger原始碼解析原始碼
- SDWebImage原始碼解析Web原始碼
- Ribbon原始碼解析原始碼
- AsyncTask原始碼解析原始碼
- linker原始碼解析原始碼
- vuex原始碼解析Vue原始碼