Android?ButterKnife依賴注入框架使用教程
簡(jiǎn)介
BuffterKnife 采用 注解+ APT技術(shù)
APT:Annotation Processor tool 注解處理器,是javac的一個(gè)工具,每個(gè)處理器都是繼承于AbstractProcessor
注解處理器是運(yùn)行在自己的java虛擬機(jī)中
APT如何生成字節(jié)碼文件:

Annotation Processing 不能加入或刪除java方法
APT整個(gè)流程
- 聲明的注解等待生命周期為CLASS
- 繼承AbstractProcessor類
- 再調(diào)用AbstractProcessor 的process方法
AbstractProcessor.java
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package javax.annotation.processing;
import java.util.Collections;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.Element;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic.Kind;
public abstract class AbstractProcessor implements Processor {
protected ProcessingEnvironment processingEnv;
private boolean initialized = false;
protected AbstractProcessor() {
}
public Set<String> getSupportedOptions() {
SupportedOptions so = (SupportedOptions)this.getClass().getAnnotation(SupportedOptions.class);
return so == null ? Collections.emptySet() : arrayToSet(so.value(), false);
}
public Set<String> getSupportedAnnotationTypes() { // 返回所支持注解的類型
SupportedAnnotationTypes sat = (SupportedAnnotationTypes)this.getClass().getAnnotation(SupportedAnnotationTypes.class);
boolean initialized = this.isInitialized();
if (sat == null) {
if (initialized) {
this.processingEnv.getMessager().printMessage(Kind.WARNING, "No SupportedAnnotationTypes annotation found on " + this.getClass().getName() + ", returning an empty set.");
}
return Collections.emptySet();
} else {
boolean stripModulePrefixes = initialized && this.processingEnv.getSourceVersion().compareTo(SourceVersion.RELEASE_8) <= 0;
return arrayToSet(sat.value(), stripModulePrefixes);
}
}
public SourceVersion getSupportedSourceVersion() { //用來指定所使用的java版本
SupportedSourceVersion ssv = (SupportedSourceVersion)this.getClass().getAnnotation(SupportedSourceVersion.class);
SourceVersion sv = null;
if (ssv == null) {
sv = SourceVersion.RELEASE_6;
if (this.isInitialized()) {
Messager var10000 = this.processingEnv.getMessager();
Kind var10001 = Kind.WARNING;
String var10002 = this.getClass().getName();
var10000.printMessage(var10001, "No SupportedSourceVersion annotation found on " + var10002 + ", returning " + sv + ".");
}
} else {
sv = ssv.value();
}
return sv;
}
public synchronized void init(ProcessingEnvironment processingEnv) { // 初始化工作
if (this.initialized) {
throw new IllegalStateException("Cannot call init more than once.");
} else {
Objects.requireNonNull(processingEnv, "Tool provided null ProcessingEnvironment");
this.processingEnv = processingEnv;
this.initialized = true;
}
}
public abstract boolean process(Set<? extends TypeElement> var1, RoundEnvironment var2); // process相對(duì)于main函數(shù),即方法的入口,在process方法中可以完成掃描、評(píng)估、處理注解等等代碼。process方法最后會(huì)生成所需要的java代碼
public Iterable<? extends Completion> getCompletions(Element element, AnnotationMirror annotation, ExecutableElement member, String userText) {
return Collections.emptyList();
}
protected synchronized boolean isInitialized() {
return this.initialized;
}
private static Set<String> arrayToSet(String[] array, boolean stripModulePrefixes) {
assert array != null;
Set<String> set = new HashSet(array.length);
String[] var3 = array;
int var4 = array.length;
for(int var5 = 0; var5 < var4; ++var5) {
String s = var3[var5];
if (stripModulePrefixes) {
int index = s.indexOf(47);
if (index != -1) {
s = s.substring(index + 1);
}
}
set.add(s);
}
return Collections.unmodifiableSet(set);
}
}ProcessingEnvironment.java
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package javax.annotation.processing;
import java.util.Locale;
import java.util.Map;
import javax.lang.model.SourceVersion;
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;
public interface ProcessingEnvironment {
Map<String, String> getOptions();
Messager getMessager();
Filer getFiler(); //用于創(chuàng)建文件
Elements getElementUtils(); //用來處理Element的工具類,Element是指在注解處理過程中掃描的所有java源文件,可以把這個(gè)源文件想象成Element的全部,而源代碼中每個(gè)獨(dú)立的部分就可以認(rèn)作為特定類型的Element
Types getTypeUtils(); //TypeElement代表Element的類型, Types是用于獲取源代碼類型的信息
SourceVersion getSourceVersion();
Locale getLocale();
}ButterKnife的工作原理
- 編譯的時(shí)候掃描注解,并做相應(yīng)的處理,生成java代碼,生成Java代碼是調(diào)用 javapoet 庫(kù)生成的
- 調(diào)用ButterKnife.bind(this);方法的時(shí)候,將ID與對(duì)應(yīng)的上下文綁定在一起
到此這篇關(guān)于Android ButterKnife依賴注入框架使用教程的文章就介紹到這了,更多相關(guān)Android ButterKnife依賴注入內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Android用注解與反射實(shí)現(xiàn)Butterknife功能
- Android中butterknife的使用與自動(dòng)化查找組件插件詳解
- 詳解Android Studio安裝ButterKnife插件(手動(dòng)安裝)
- Android Studio使用ButterKnife和Zelezny的方法
- Android Kotlin環(huán)境使用ButterKnife的方法
- Android Studio中ButterKnife插件的安裝與使用詳解
- 解決Android Studio 3.0 butterknife:7.0.1配置的問題
- Android注解使用之ButterKnife 8.0詳解
- Android注解ButterKnife的基本使用
相關(guān)文章
Android4.4開發(fā)之電池低電量告警提示原理與實(shí)現(xiàn)方法分析
這篇文章主要介紹了Android4.4開發(fā)之電池低電量告警提示原理與實(shí)現(xiàn)方法,結(jié)合實(shí)例形式分析了Android4.4電池電量警告的原理及相關(guān)操作技巧,需要的朋友可以參考下2017-09-09
Android仿微信公眾號(hào)文章頁(yè)面加載進(jìn)度條
這篇文章主要為大家詳細(xì)介紹了Android仿微信公眾號(hào)文章頁(yè)面加載進(jìn)度條,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-06-06
Android應(yīng)用程序簽名步驟及相關(guān)知識(shí)介紹
本文主要介紹Android應(yīng)用程序簽名相關(guān)的理論知識(shí),包括:什么是簽名、為什么要給應(yīng)用程序簽名、如何給應(yīng)用程序簽名等,感興趣的朋友可以參考下哈2013-04-04
Android使用VideoView播放本地視頻和網(wǎng)絡(luò)視頻的方法
本文將講解如何使用Android視頻播放器VideoView來播放本地視頻和網(wǎng)絡(luò)視頻,實(shí)現(xiàn)起來還是比較簡(jiǎn)單的,有需要的可以參考借鑒。2016-08-08
Android Tween動(dòng)畫之RotateAnimation實(shí)現(xiàn)圖片不停旋轉(zhuǎn)效果實(shí)例介紹
Android中如何使用rotate實(shí)現(xiàn)圖片不停旋轉(zhuǎn)的效果,下面與大家共同分析下Tween動(dòng)畫的rotate實(shí)現(xiàn)旋轉(zhuǎn)效果,感興趣的朋友可以參考下哈2013-05-05
Android自定義View實(shí)現(xiàn)仿1號(hào)店垂直滾動(dòng)廣告條代碼
這篇文章主要介紹了Android自定義View實(shí)現(xiàn)仿1號(hào)店垂直滾動(dòng)廣告條代碼,實(shí)現(xiàn)步驟及實(shí)現(xiàn)原理本文給大家介紹的非常詳細(xì),需要的朋友參考下吧2017-01-01
解析Android 8.1平臺(tái)SystemUI 導(dǎo)航欄加載流程
這篇文章主要介紹了Android 8.1平臺(tái)SystemUI 導(dǎo)航欄加載流程,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-11-11
Android ImageView Src 和Background 區(qū)別
這篇文章主要介紹了Android ImageView Src 和Background 區(qū)別的相關(guān)資料,需要的朋友可以參考下2016-09-09
Android通過實(shí)現(xiàn)GridView的橫向滾動(dòng)實(shí)現(xiàn)仿京東秒殺效果
這篇文章主要介紹了Android通過實(shí)現(xiàn)GridView的橫向滾動(dòng)實(shí)現(xiàn)仿京東秒殺效果,實(shí)現(xiàn)代碼簡(jiǎn)單易懂,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-07-07

