Android ButterKnife依赖注入框架使用教程

目录
  • 简介
  • APT整个流程
  • ButterKnife的工作原理

简介

BuffterKnife 采用 注解+ APT技术

APT:Annotation Processor tool 注解处理器,是javac的一个工具,每个处理器都是继承于AbstractProcessor

注解处理器是运行在自己的java虚拟机中

APT如何生成字节码文件:

Annotation Processing 不能加入或删除java方法

APT整个流程

  • 声明的注解等待生命周期为CLASS
  • 继承AbstractProcessor类
  • 再调用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相对于main函数,即方法的入口,在process方法中可以完成扫描、评估、处理注解等等代码。process方法最后会生成所需要的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();  //用于创建文件
    Elements getElementUtils();  //用来处理Element的工具类,Element是指在注解处理过程中扫描的所有java源文件,可以把这个源文件想象成Element的全部,而源代码中每个独立的部分就可以认作为特定类型的Element
    Types getTypeUtils();  //TypeElement代表Element的类型, Types是用于获取源代码类型的信息
    SourceVersion getSourceVersion();
    Locale getLocale();
}

ButterKnife的工作原理

  • 编译的时候扫描注解,并做相应的处理,生成java代码,生成Java代码是调用 javapoet 库生成的
  • 调用ButterKnife.bind(this);方法的时候,将ID与对应的上下文绑定在一起

到此这篇关于Android ButterKnife依赖注入框架使用教程的文章就介绍到这了,更多相关Android ButterKnife依赖注入内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Android用注解与反射实现Butterknife功能

    目录 自定义注解 使用自定义注解 通过反射机制获取注解参数 1. 布局文件获取 2. 控件获取实现 3. 控件点击响应 自定义注解 1) 先定义布局文件注入 //注解的作用域在类上 @Target(ElementType.TYPE) //让保持性策略为运行时态,将注解编码到class文件中,让虚拟机读取 @Retention(RetentionPolicy.RUNTIME) public @interface ContentView { int value();//使用时直接@ContentVi

  • Android注解使用之ButterKnife 8.0详解

    前言: App项目开发大部分时候还是以UI页面为主,这时我们需要调用大量的findViewById以及setOnClickListener等代码,控件的少的时候我们还能接受,控件多起来有时候就会有一种想砸键盘的冲动.所以这个时候我们想着可以借助注解的方式让我们从这种繁重的工作中脱离出来,也让代码变得更加简洁,便于维护,今天主要学习一下只专注View.Resource.Action注解框架ButterKnife. ButterKnife介绍 ButterKnife是一个专注于Android系统的V

  • Android Studio使用ButterKnife和Zelezny的方法

    前言 ButterKnife是一个专注于Android的View注入框架,可以减少大量的findViewById以及setOnClickListener代码,可视化一键生成. 有着以下的优点: 1.强大的View绑定和Click事件处理功能,简化代码,提升开发效率 2.方便的处理Adapter里的ViewHolder绑定问题 3.运行时不会影响APP效率,使用配置方便 4.代码清晰,可读性强 Android Studio配置ButterKnife 第一步 第二步 配置project的build.

  • 解决Android Studio 3.0 butterknife:7.0.1配置的问题

    网上教程7.0大多数配置是这样compile 'com.jakewharton:butterknife:7.0.1' ,不知道他们用的Android Studio是多少版本,我用的3.0并没有成功,报错如下: Error:Execution failed for task ':app:javaPreCompileDebug'. Annotation processors must be explicitly declared now. The following dependencies on

  • 详解Android Studio安装ButterKnife插件(手动安装)

    写完布局后 我们一般需要 findViewById找到这个控件,但是现在有一个很好用的插件ButterKnife 可以一键转化布局文件中的所有有id属性的控件到activitry中:现在我们介绍下此插件使用: 通过AndroidStudio 下载安装 1.打开Android Studio中的设置界面,并且点击左边的插件Plugins,在搜索框中输入 Android ButterKnife Zelezny 如图: 点击 Search in repositories 如图: 点击 install就自

  • Android Studio中ButterKnife插件的安装与使用详解

    1>Android Studio 安装ButterKnife插件 同安装其他插件类似,如下: 1.1>打开Plugins界面 按照上图中1,2,3指示操作(注意:这里我的Android Studio中已经安装了该插件,所以显示的内容不太一样).然后重启Android Studio. 2>在项目上使用该开源项目(以Android Studio 为例) 2.1>在bulid.gradle中添加依赖 重新编译一下该项目,通过后继续操作. 2.2>在代码中就可以使用注解的方式了 2.

  • Android中butterknife的使用与自动化查找组件插件详解

    前言 Android开发中经常使用findViewById来获取控件然后进行一些列操作,当控件太多的时候代码就非常臃肿,今天就来学习一个新的开源库ButterKnife,真的可以帮助我们高效,快捷的开发,让我们的代码更加简洁. 首先我们来把ButterKnife集成在我们的项目中:ButterKnife的GitHub官方地址:github.com/JakeWharton- 一.集成分为了两部分: 1.仅仅在App主工程使用: 在App的 build.gradle 中添加如下代码: android

  • Android Kotlin环境使用ButterKnife的方法

    Butter Knife 黄油刀大家应该都挺熟悉的,有这个之后,就不用写一堆的findViewById,体力活,最近试着玩玩Kotlin语言,也就尝试在Kotlin语言环境下使用ButterKnife,有一点小问题,解决并分享一下. 先看看java环境的用法 1.安装插件,然后重启Android studio. 安装插件.jpg 2.使用,点击一下在setContentView(R.layout.activity_main);然后快捷键Alt+insert. Alt+insert.jpg 3.使

  • Android注解ButterKnife的基本使用

    ButterKnife的最新版本是8.4.0. 首先,需要导入ButterKnife的jar包. 在AndroidStudio中,File->Project Structure->Dependencies->Library dependency 搜索butterknife即可,第一个就是. 另外一种就是直接在build:grade(app)dependencies里添加: compile 'com.jakewharton:butterknife:8.4.0' annotationProc

  • Android ButterKnife依赖注入框架使用教程

    目录 简介 APT整个流程 ButterKnife的工作原理 简介 BuffterKnife 采用 注解+ APT技术 APT:Annotation Processor tool 注解处理器,是javac的一个工具,每个处理器都是继承于AbstractProcessor 注解处理器是运行在自己的java虚拟机中 APT如何生成字节码文件: Annotation Processing 不能加入或删除java方法 APT整个流程 声明的注解等待生命周期为CLASS 继承AbstractProcess

  • 浅析依赖注入框架Autofac的使用

    下面通过代码给大家分享下依赖注入框架Autofac的使用,具体如下所示:  Autofac是一款IOC框架,比较于其他的IOC框架,如Spring.NET,Unity,Castle等等所包含的,它很轻量级性能上也是很高的. 1)解压它的压缩包,主要看到Autofac.dll,Autofac.Configuration.dll,这也是本篇文章重点使用的Autofac的类库. 2)创建一个控制台工程,并且引用以上的DLL文件.创建一个数据库操作接口IDatabase.cs: /// <summary

  • 200行Java代码如何实现依赖注入框架详解

    依赖注入介绍 先回顾下依赖注入的概念: 我们常提起的依赖注入(Dependency Injection)和控制反转(Inversion of Control)是同一个概念.具体含义是:当某个角色(可能是一个Java实例,调用者)需要另一个角色(另一个Java实例,被调用者)的协助时,在 传统的程序设计过程中,通常由调用者来创建被调用者的实例.但在Spring里,创建被调用者的工作不再由调用者来完成,因此称为控制反转;创建被调用者 实例的工作通常由Spring容器来完成,然后注入调用者,因此也称为

  • ASP.NET Core  依赖注入框架的使用

    目录 一.IoC框架 二.IoC-Autofac 三..NET Core中自带DI的使用 四.Autofac 使用 五.批量注入 前言: 还记得上篇文章中ASP.NET Core 依赖注入详细最后提及到,假如服务越来越多怎么处理呢,本篇文章将会带来解决办法.这篇是接上一篇文章的,概念方面的可以参考上一篇文章. 一.IoC框架 先说说常见的Ioc框架吧. Autofac: 目前net用的比较多,好多大佬的项目比较优先选择的框架. Ninject: 已经很少用了,还时在很早的文章中见过. Unity

  • Asp.net core程序中使用微软的依赖注入框架

    我之前在博文中介绍过Asp.net core下系统自带的依赖注入框架,这个依赖框架在Microsoft.Extensions.DependencyInjection中实现,本身并不是.net core的一部分(是asp.net core的一部分),本文这里就简单的介绍下载.net core控制台程序中使用这个框架,顺便也了解下这个框架的全貌. 首先我们需要安装Microsoft.Extensions.DependencyInjection这个Nuget包,也可以直接使用Microsoft.Asp

  • Android Hilt依赖注入的使用讲解

    目录 什么是依赖注入 使用依赖注入的好处 Hilt中常用的预定义限定符 @HiltAndroidApp @AndroidEntryPoint @Module @InstallIn @Provides @Inject @HiltViewModel Hilt的使用 依赖 建立实体类 添加Hilt入口 提供对象 获取对象 应用与ViewModel中 使用 总结 什么是依赖注入 首先,某个类的成员变量称为依赖,如若此变量想要实例化引用其类的方法,可以通过构造函数传参或者通过某个方法获取对象,此等通过外部

  • Go语言官方依赖注入工具Wire的使用教程

    目录 1. 前言 2. 依赖注入(DI)是什么 3. Wire Come 3.1 简介 3.2 快速使用 3.3 基础概念 4. Wire使用实践 4.1 基础使用 4.2 高级特性 4.3 高阶使用 5. 注意事项 5.1 相同类型问题 5.2 单例问题 6. 结语 1. 前言 接触 Golang 有一段时间了,发现 Golang 同样需要类似 Java 中 Spring 一样的依赖注入框架.如果项目规模比较小,是否有依赖注入框架问题不大,但当项目变大之后,有一个合适的依赖注入框架是十分必要的

  • ABP框架的基础配置及依赖注入讲解

    配置ABP 配置是通过在自己模块的PreInitialize方法中来实现的 代码示例如下: public class SimpleTaskSystemModule : AbpModule { public override void PreInitialize() { //在你的应用中添加语言包,这个是英语和作者的土耳其语. Configuration.Localization.Languages.Add(new LanguageInfo("en", "English&quo

  • 解读ASP.NET 5 & MVC6系列教程(7):依赖注入

    在前面的章节(Middleware章节)中,我们提到了依赖注入功能(Dependency Injection),ASP.NET 5正式将依赖注入进行了全功能的实现,以便开发人员能够开发更具弹性的组件程序,MVC6也利用了依赖注入的功能重新对Controller和View的服务注入功能进行了重新设计:未来的依赖注入功能还可能提供更多的API,所有如果还没有开始接触依赖注入的话,就得好好学一下了. 在之前版本的依赖注入功能里,依赖注入的入口有MVC中的IControllerFactory和Web A

  • Java元注解meta-annotation和依赖注入详解

    这篇文章既介绍一个技术,又记录一个逐渐探索发现的过程,以供大家参考. 缘起 注意到Java的依赖注入DI规范(起初以为是CDI规范,然后发现是DI规范)有个叫@Qualifier的注解,用于当一个interface或base class有多个实现类时,能选择其中一个实现.如不用这一注解,一般的(按类型)注入就会报错说"不知道要在多个实现中选哪一个".这一注解可以放在一个自定义注解上(例如@MyPreferredImplementation),从而将自定义注解变成一个qualifier

随机推荐