到此我们整个的流程算分析完了。

最后我们看下对外提供的API

bind 方法

那么还差一步,什么时候都要我们生成的java文件呢?答案是:
ButterKnife.bind(this);方法。
我们看一下ButterKnife对外提供的API

/*** BindView annotated fields and methods in the specified {@link Activity}. The current content* view is used as the view root.** @param target Target activity for view binding.*/@NonNull @UiThreadpublic static Unbinder bind(@NonNull Activity target) {View sourceView = target.getWindow().getDecorView();return createBinding(target, sourceView);}/*** BindView annotated fields and methods in the specified {@link View}. The view and its children* are used as the view root.** @param target Target view for view binding.*/@NonNull @UiThreadpublic static Unbinder bind(@NonNull View target) {return createBinding(target, target);}/*** BindView annotated fields and methods in the specified {@link Dialog}. The current content* view is used as the view root.** @param target Target dialog for view binding.*/@NonNull @UiThreadpublic static Unbinder bind(@NonNull Dialog target) {View sourceView = target.getWindow().getDecorView();return createBinding(target, sourceView);}/*** BindView annotated fields and methods in the specified {@code target} using the {@code source}* {@link Activity} as the view root.** @param target Target class for view binding.* @param source Activity on which IDs will be looked up.*/@NonNull @UiThreadpublic static Unbinder bind(@NonNull Object target, @NonNull Activity source) {View sourceView = source.getWindow().getDecorView();return createBinding(target, sourceView);}/*** BindView annotated fields and methods in the specified {@code target} using the {@code source}* {@link View} as the view root.** @param target Target class for view binding.* @param source View root on which IDs will be looked up.*/@NonNull @UiThreadpublic static Unbinder bind(@NonNull Object target, @NonNull View source) {return createBinding(target, source);}/*** BindView annotated fields and methods in the specified {@code target} using the {@code source}* {@link Dialog} as the view root.** @param target Target class for view binding.* @param source Dialog on which IDs will be looked up.*/@NonNull @UiThreadpublic static Unbinder bind(@NonNull Object target, @NonNull Dialog source) {View sourceView = source.getWindow().getDecorView();return createBinding(target, sourceView);}private static Unbinder createBinding(@NonNull Object target, @NonNull View source) {Class<?> targetClass = target.getClass();if (debug) Log.d(TAG, "Looking up binding for " + targetClass.getName());Constructor<? extends Unbinder> constructor = findBindingConstructorForClass(targetClass);if (constructor == null) {return Unbinder.EMPTY;}//noinspection TryWithIdenticalCatches Resolves to API 19+ only type.try {return constructor.newInstance(target, source);} catch (IllegalAccessException e) {throw new RuntimeException("Unable to invoke " + constructor, e);} catch (InstantiationException e) {throw new RuntimeException("Unable to invoke " + constructor, e);} catch (InvocationTargetException e) {Throwable cause = e.getCause();if (cause instanceof RuntimeException) {throw (RuntimeException) cause;}if (cause instanceof Error) {throw (Error) cause;}throw new RuntimeException("Unable to create binding instance.", cause);}}

我们看到bind的一系列方法都会调用createBinding方法

   private static Unbinder createBinding(@NonNull Object target, @NonNull View source) {Class<?> targetClass = target.getClass();if (debug) Log.d(TAG, "Looking up binding for " + targetClass.getName());Constructor<? extends Unbinder> constructor = findBindingConstructorForClass(targetClass);if (constructor == null) {return Unbinder.EMPTY;}//noinspection TryWithIdenticalCatches Resolves to API 19+ only type.try {return constructor.newInstance(target, source);} catch (IllegalAccessException e) {throw new RuntimeException("Unable to invoke " + constructor, e);} catch (InstantiationException e) {throw new RuntimeException("Unable to invoke " + constructor, e);} catch (InvocationTargetException e) {Throwable cause = e.getCause();if (cause instanceof RuntimeException) {throw (RuntimeException) cause;}if (cause instanceof Error) {throw (Error) cause;}throw new RuntimeException("Unable to create binding instance.", cause);}}

Class<\?> (?是转义字符csdn要不支持)targetClass = target.getClass();获取类的实例,最后获取构造函数,最后constructor.newInstance方法来调用该类的构造函数。
而该类的构造函数是通过findBindingConstructorForClass方法,我可没来看下此方法:

   @Nullable @CheckResult @UiThreadprivate static Constructor<? extends Unbinder> findBindingConstructorForClass(Class<?> cls) {//缓存中查找,找到直接返回Constructor<? extends Unbinder> bindingCtor = BINDINGS.get(cls);if (bindingCtor != null) {if (debug) Log.d(TAG, "HIT: Cached in binding map.");return bindingCtor;}//检查合法性String clsName = cls.getName();if (clsName.startsWith("android.") || clsName.startsWith("java.")) {if (debug) Log.d(TAG, "MISS: Reached framework class. Abandoning search.");return null;}try {//构造一个class,可以看类名就是我们生成的。Class<?> bindingClass = Class.forName(clsName + "_ViewBinding");//noinspection unchecked// 获取我们的构造函数bindingCtor = (Constructor<? extends Unbinder>) bindingClass.getConstructor(cls, View.class);if (debug) Log.d(TAG, "HIT: Loaded binding class and constructor.");} catch (ClassNotFoundException e) {if (debug) Log.d(TAG, "Not found. Trying superclass " + cls.getSuperclass().getName());bindingCtor = findBindingConstructorForClass(cls.getSuperclass());} catch (NoSuchMethodException e) {throw new RuntimeException("Unable to find binding constructor for " + clsName, e);}//加入到缓存中BINDINGS.put(cls, bindingCtor);return bindingCtor;}

可以看到用到了简单的缓存。

unbind 方法

在新版的8.4.0中去除了 unbind方法。

ButterKnife.unbind(this);

采用了接口的形式。让生成的类来实现,比如:

 public final class SimpleAdapter$ViewHolder_ViewBinding implements Unbinder {@UiThreadpublic SimpleAdapter$ViewHolder_ViewBinding(SimpleAdapter.ViewHolder target, View source) {//...}//...@Overridepublic void unbind() {/...}}

那如何unbind呢??
ButterKnife.bind(this)返回值是一个我们生成的java文件类的实例对象。返回的是一个Unbinder 正和此意。
so,你可以这么用:

  private  Unbinder unbinder;     @Override protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.simple_activity);unbinder=ButterKnife.bind(this);}@Overrideprotected void onDestroy() {super.onDestroy();unbinder.unbind();}

到此我们就算完了。


下一篇我们讲自己来实现类似butterknife的demo,这样我们才能正在的会学,会用。
下一篇
深入理解ButterKnife源码并掌握原理(五)

深入理解ButterKnife源码并掌握原理(四)相关推荐

  1. 深入理解ButterKnife源码并掌握原理(三)

    上两篇我们分析完了处理器的process方法的findAndParseTargets方法来获取了一个集合,该集合包含了你使用注解的类的TypeElement和这个类中的注解的实例BindingClas ...

  2. 深入理解ButterKnife源码并掌握原理(二)

    好,我们接着parseBindView的步骤3 ,忘记了在哪里了,咦. 可以看下上一篇,哈哈. 步骤3 BindingClass bindingClass = targetClassMap.get(e ...

  3. 深入理解ButterKnife源码并掌握原理(一)

    前言 话说在android这座大山里,有一座庙(方块公司-square),庙里住着一个神-jake(我是这么叫的嘻嘻). 不要小看这个小jake,这个神可是为android应用开发们提供了强有力的帮助 ...

  4. 深入理解ButterKnife源码并掌握原理(五)

    前面四篇是自己参考有关知识和分析ButterKnife源码后写的,如果有不对的地方,还望指导下. 这一篇是实践篇.我们的目的是学会原理来变为自己的知识. 这个demo所使用的原理就是ButterKni ...

  5. MyBatis 源码分析 - 缓存原理

    1.简介 在 Web 应用中,缓存是必不可少的组件.通常我们都会用 Redis 或 memcached 等缓存中间件,拦截大量奔向数据库的请求,减轻数据库压力.作为一个重要的组件,MyBatis 自然 ...

  6. Tomcat7.0源码分析——请求原理分析(上)

    前言 谈起Tomcat的诞生,最早可以追溯到1995年.近20年来,Tomcat始终是使用最广泛的Web服务器,由于其使用Java语言开发,所以广为Java程序员所熟悉.很多早期的J2EE项目,由程序 ...

  7. 【赠书福利】掘金爆火小册同名《Spring Boot源码解读与原理剖析》正式出书了!...

    关注我们丨文末赠书 承载着作者的厚望,掘金爆火小册同名读物<Spring Boot源码解读与原理剖析>正式出书! 本书前身是掘金社区销量TOP的小册--<Spring Boot源码解 ...

  8. 遍历HashMap源码——红黑树原理、HashMap红黑树实现与反树型化(三)

    本章将是HashMap源码的最后一章,将介绍红黑树及其实现,HashMap的remove方法与反树型化.长文预警~~ 遍历HashMap源码--红黑树原理.HashMap红黑树实现与反树型化 什么是红 ...

  9. Java基础笔记(2)——HashMap的源码,实现原理,底层结构是怎么样的

    Java基础笔记(2)--HashMap的源码,实现原理,底层结构是怎么样的 HashMap的源码,实现原理,底层结构 1.HashMap: HashMap是基于哈希表的 Map 接口的实现.此实现提 ...

最新文章

  1. 关于python赋值语句下列选项中描述正确的是_关于Python的分支结构,以下选项中描述正确的是()。...
  2. 基于nginx实现反向代理
  3. HTML5实现屏幕手势解锁(转载)
  4. c语言字符串数组的合并,C语言实现合并字符串
  5. xml文件 卷积神经网络_理解卷积神经网络中的输入与输出形状(Keras实现)
  6. 在centos上搭建redis集群并附测试(真集群非伪集群)
  7. 力扣- - 最短回文串(KMP算法)
  8. oraoledb.oracle 12c,关于OraOLEDB.Oracle找不到驱动问题的一种可能解决方案
  9. 百度AI智能小程序正式开放申请
  10. 罗永浩回应被列入老赖名单:就算“卖艺”也会把债务还完
  11. android 10 apk 存储适配,AndroidQ(10) 分区存储适配方法
  12. Spring mvc 参数类型转换
  13. 实验一 框架的选择及其原因
  14. 使用memcachedclientXmemcached与Spring整合
  15. Filecoin网络目前总质押量约为4110万枚FIL
  16. 二分法实战教学快速入门(折半查找法)
  17. Android Vendor Test Suite (VTS) 作用及测试方法
  18. 系统架构师必须掌握的英语单词
  19. JAVA POI EXCEL导出工具方法 支持冻结列行和设置不可编辑整行整列
  20. 计算机如何理解图像?

热门文章

  1. (转)SQL Server数据库状态监控 - 作业状态
  2. B-TrunC标准加入ITU集群国际标准
  3. SQL Server中CTE的另一种递归方式-从底层向上递归
  4. 开源 免费 java CMS - FreeCMS1.3-信息管理
  5. 【转载】用备份进行Active Directory的灾难重建:Active Directory系列之三
  6. 在django中实现表单
  7. MySQL更新行和插入列的语句
  8. oracle改表结构非空字段类型,oracle 表结构的非完全复制
  9. java判断integer是否为空_java安全编码指南之:表达式规则
  10. 学土木结构考计算机等级考试,请教各位,我是学土木的,考计算机二级的哪个比较好?...