注解初始化控件(ButterKnife方式)

在学习了XUtils的注入方式之后,看了下ButterKnife的实现方式,结果发现完全不一样,然后借鉴网上的博客,结果发现用的都是Eclipse以及旧版本的ButterKnife进行实现的。

这里我用AndroidStudio根据ButterKnife的版本进行了实现。

先看下ButterKnife中生成的java代码(看看骚包的注释 Do not modify!)

// Generated code from Butter Knife. Do not modify!
package com.example.butterknife;

import android.view.View;
import android.widget.AdapterView;
import butterknife.ButterKnife;
import butterknife.internal.DebouncingOnClickListener;
import butterknife.internal.Finder;
import butterknife.internal.Utils;
import butterknife.internal.ViewBinder;
import java.lang.IllegalStateException;
import java.lang.Object;
import java.lang.Override;
import java.lang.SuppressWarnings;

public class SimpleActivity$$ViewBinder<T extends SimpleActivity> implements ViewBinder<T> {
  @Override
  public void bind(final Finder finder, final T target, Object source) {
    Unbinder unbinder = createUnbinder(target);
    View view;
    view = finder.findRequiredView(source, 2130968576, "field 'title'");
    target.title = finder.castView(view, 2130968576, "field 'title'");
    view = finder.findRequiredView(source, 2130968577, "field 'subtitle'");
    target.subtitle = finder.castView(view, 2130968577, "field 'subtitle'");
    view = finder.findRequiredView(source, 2130968578, "field 'hello', method 'sayHello', and method 'sayGetOffMe'");
    target.hello = finder.castView(view, 2130968578, "field 'hello'");
    unbinder.view2130968578 = view;
    view.setOnClickListener(new DebouncingOnClickListener() {
      @Override
      public void doClick(View p0) {
        target.sayHello();
      }
    });
    view.setOnLongClickListener(new View.OnLongClickListener() {
      @Override
      public boolean onLongClick(View p0) {
        return target.sayGetOffMe();
      }
    });
    view = finder.findRequiredView(source, 2130968579, "field 'listOfThings' and method 'onItemClick'");
    target.listOfThings = finder.castView(view, 2130968579, "field 'listOfThings'");
    unbinder.view2130968579 = view;
    ((AdapterView<?>) view).setOnItemClickListener(new AdapterView.OnItemClickListener() {
      @Override
      public void onItemClick(AdapterView<?> p0, View p1, int p2, long p3) {
        target.onItemClick(p2);
      }
    });
    view = finder.findRequiredView(source, 2130968580, "field 'footer'");
    target.footer = finder.castView(view, 2130968580, "field 'footer'");
    target.headerViews = Utils.listOf(
        finder.<View>findRequiredView(source, 2130968576, "field 'headerViews'"), 
        finder.<View>findRequiredView(source, 2130968577, "field 'headerViews'"), 
        finder.<View>findRequiredView(source, 2130968578, "field 'headerViews'"));
    target.unbinder = unbinder;
  }

  @SuppressWarnings("unchecked")
  protected <U extends Unbinder<T>> U createUnbinder(T target) {
    return (U) new Unbinder(target);
  }

  @SuppressWarnings("unchecked")
  protected <U extends Unbinder<T>> U accessUnbinder(T target) {
    return (U) target.unbinder;
  }

  public static class Unbinder<T extends SimpleActivity> implements ButterKnife.ViewUnbinder<T> {
    private T target;

    View view2130968578;

    View view2130968579;

    protected Unbinder(T target) {
      this.target = target;
    }

    @Override
    public final void unbind() {
      if (target == null) throw new IllegalStateException("Bindings already cleared.");
      unbind(target);
      target = null;
    }

    protected void unbind(T target) {
      target.title = null;
      target.subtitle = null;
      view2130968578.setOnClickListener(null);
      view2130968578.setOnLongClickListener(null);
      target.hello = null;
      ((AdapterView<?>) view2130968579).setOnItemClickListener(null);
      target.listOfThings = null;
      target.footer = null;
      target.headerViews = null;
      target.unbinder = null;
    }
  }
}

XUtils 与 ButterKnife实现方式的区别

上篇XUtils实现注解初始化用的是反射 + 动态代理

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

而ButterKnife使用的是APT (Annotation Processing Tool )

apt是一个命令行工具,与之配套的还有一套用来描述程序语义结构的Mirror API。Mirror API(com.sun.mirror.*)描述的是程序在编译时刻的静态结构。通过Mirror API可以获取到被注解的Java类型元素的信息,从而提供相应的处理逻辑。具体的处理工作交给apt工具来完成。编写注解处理器的核心是AnnotationProcessorFactory和AnnotationProcessor两个接口。后者表示的是注解处理器,而前者则是为某些注解类型创建注解处理器的工厂。

参考资料

• Java注解
• JDK 5和JDK 6中的apt工具说明文档
• Pluggable Annotation Processing API
• APT: Compile-Time Annotation Processing with Java

Mirror的五大Element

PackageElement 包元素
TypeElement 类元素
VariableElement 变量元素
ExecutableElement 方法元素
TypeParameterElement 参数元素

你可能感兴趣的:(ButterKnif,控件初始化)