版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhang___yong/article/details/82113511
引入:
implementation 'com.jakewharton:butterknife:8.5.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.5.1'
butterknife的工作原理是在编译器根据扫描的注解通过JavaPoet生成一个和target(activity,fragment)对应的java文件A.java,这个生成类A(extends UnBinder)的构造方法中完成了一切实质的的绑定操作。在target中调用了bind(this)后,通过反射(target类名+_ViewBinding)获取A的构造器并实例化返回。
来看个代码,我在MainActivity中用@BindView修饰SurfaceView sv,然后make project。生成了MainActivity_ViewBinding:
// Generated code from Butter Knife. Do not modify!
package com.example.zhangyong.myapplication;
import android.support.annotation.CallSuper;
import android.support.annotation.UiThread;
import android.view.SurfaceView;
import android.view.View;
import butterknife.Unbinder;
import butterknife.internal.Utils;
import java.lang.IllegalStateException;
import java.lang.Override;
public class MainActivity_ViewBinding implements Unbinder {
private MainActivity target;
@UiThread
public MainActivity_ViewBinding(MainActivity target) {
this(target, target.getWindow().getDecorView());
}
@UiThread
public MainActivity_ViewBinding(MainActivity target, View source) {
this.target = target;
target.sv = Utils.findRequiredViewAsType(source, R.id.sv, "field 'sv'", SurfaceView.class);
}
@Override
@CallSuper
public void unbind() {
MainActivity target = this.target;
if (target == null) throw new IllegalStateException("Bindings already cleared.");
this.target = null;
target.sv = null;
}
}
可以看到构造器接收的参数是MainActivity,然后对被注解的属性(非private和static)进行操作,最终走的肯定还是findViewById,只不过是调用了DecorView的findViewById,可以进findRequiredViewAsType看看。
其他的一些注解就差不多了,比如设置点击事件什么的,拿到了MainActivity,也就拿到了view。
unBind里就是对这些属性赋值null,target=null的一步避免了内存泄漏。