ButterKnife 0

分析bind流程

Activity綁定
ButterKnife.bind(this);bind源碼如下 :

/**
   * 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 @UiThread
  public static Unbinder bind(@NonNull Activity target) {
    View sourceView = target.getWindow().getDecorView();
    return createBinding(target, sourceView);
  }

return一個(gè)Unbinder對(duì)象,Unbinder是一個(gè)接口, 當(dāng)Activity 銷(xiāo)毀時(shí)取消綁定

package butterknife;

import android.support.annotation.UiThread;

/** An unbinder contract that will unbind views when called. */
public interface Unbinder {
  @UiThread void unbind();

  Unbinder EMPTY = new Unbinder() {
    @Override public void unbind() { }
  };
}

NOTE:UiThread是官方support annitation庫(kù)提供的一個(gè)注解

先獲取Activity的DecorView, 調(diào)用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);
    }
  }

調(diào)用findBindingConstructorForClass獲取Constructor,通過(guò)反射再執(zhí)行newInstance生成Unbinder對(duì)象,關(guān)鍵函數(shù)findBindingConstructorForClass如下:

@Nullable @CheckResult @UiThread
  private 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<?> 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;
  }

可以看出BINDINGS鍵值對(duì)映射了class和對(duì)應(yīng)的Constructor, 而Constructor是xxx_ViewBinding(xxx指某個(gè)Activity)的構(gòu)造器,這個(gè)xxx_ViewBinding并不是我們手寫(xiě)的java類(lèi),是annotation processor生成的,這個(gè)單開(kāi)一篇來(lái)說(shuō)明

結(jié)論

ButterKnife.bind(this);返回一個(gè)Unbinder接口,實(shí)例化的是Activity_ViewBinding對(duì)象

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,657評(píng)論 19 139
  • 前言:ButterKnife是一個(gè)專(zhuān)注于Android系統(tǒng)的View注入框架,以前總是要寫(xiě)很多findViewBy...
    Donkor閱讀 10,478評(píng)論 3 23
  • 前言 這個(gè)框架大家都是特別熟悉的了,JakeWharton大神的作品,項(xiàng)目地址,怎么用我就不多講了,可以去參考官方...
    foxleezh閱讀 1,486評(píng)論 0 7
  • 最近項(xiàng)目不是很忙,因?yàn)轫?xiàng)目用到了butterknife框架,所以進(jìn)行了下系統(tǒng)的研究。研究下來(lái)呢發(fā)現(xiàn)這個(gè)框架真的是吊...
    我小時(shí)候真的可狠了閱讀 369評(píng)論 0 2
  • 俗話(huà)說(shuō)的好“不想偷懶的程序員,不是好程序員”,我們?cè)谌粘i_(kāi)發(fā)android的過(guò)程中,在前端activity或者fr...
    蛋西閱讀 5,072評(píng)論 0 14

友情鏈接更多精彩內(nèi)容