butterKnife框架简介
ButterKnife是一个专注于Android系统的View注入框架,以前总是要写很多findViewById来找到View对象,有了ButterKnife可以很轻松的省去这些步骤。
ButterKnife->针对UI注解类框架
->设置监听器查找控件
->省略findviewbyid,setOnclicklistener
1.导入依赖
2.声明控件变量->访问修饰符不能为private->影响注入控件对象
3.使用@BindView绑定控件
4.使用@Onclik添加点击事件
依赖:
implementation 'com.jakewharton:butterknife:8.8.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
activity
public class MainActivity extends AppCompatActivity {
@BindView(R.id.my_RecyclerView)
public RecyclerView recyclerView;
ArrayList<String> arrayList = new ArrayList<>();
MyRecycleView_Adapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
arrayList.add("呵呵");
arrayList.add("哈哈");
arrayList.add("嘿嘿");
adapter = new MyRecycleView_Adapter(arrayList,this);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(adapter);
}
}
public class MyRecycleView_Adapter extends RecyclerView.Adapter<MyRecycleView_Adapter.MyViewHolder> {
ArrayList<String> arrayList;
Context context;
public MyRecycleView_Adapter(ArrayList<String> arrayList, Context context) {
this.arrayList = arrayList;
this.context = context;
}
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(context).inflate(R.layout.my_recycleview_item,viewGroup,false);
return new MyViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull MyViewHolder myViewHolder, int i) {
myViewHolder.textView.setText(arrayList.get(i));
}
@Override
public int getItemCount() {
return arrayList.size();
}
class MyViewHolder extends RecyclerView.ViewHolder{
@BindView(R.id.item_text)
TextView textView;
public MyViewHolder(@NonNull View itemView) {
super(itemView);
ButterKnife.bind(this,itemView);
}
}
}
Dagger2
框架说明
减少样板代码;提高重用性,测试性,可维护性.
用@Inject写到对象类的构造函数上面,要用的时候直接注入对象,避免new对象,造成强耦合。且可以加上注释@Singleton形成单例;
以@module和@provides为基础,可以任意注入对象,且可以带参操作。Module里面若是要有其他Module,要在includes里写好,@Module除了include,还有injects参数指定注入位置,library指定是否需要外部库,complete是否是完整module(含有外部module依赖则不完整)。最后在注入目的地,通过ObjectGraph(对象图表)形成依赖关系,具体操作方式,ObjectGraph对象,并调用方法create(Module).inject(注入对象);则可以直接用@inject注入目标对象类里。
Dagger2与butterknife区别
Buffer knife目的为注入到view,所以能够在非activity里面注入,也能注入到inflate的views里面;
Dagger能够注入到任何你想要的对象,只要其在module类中。或者它是构造器。但是缺少对方法和字段的注入支持;
Buffer knife只是避免样板代码,findViewById,仅此而已,所以不能算是一个真正的注入。只是一个view的代言;
对于Dagger我们可以把它当做应用中的一个模块,
负责为其它模块提供实例并且注入依赖关系。那是它的基本职责。模块的创建位于我们应用中的一个点上,这样我们可以拥有完全的控制权。Dagger
Leiva说,特别适合用在低端设备上,因为它没有采取反射而使用了预编译技术,因为基于反射的DI非常占用资源和耗时。Dagger或许不是最理想的依赖注入框架,但Leiva认为,它是最高效的。
Dagger2依赖导入:
implementation 'com.google.dagger:dagger:2.19'
annotationProcessor 'com.google.dagger:dagger-compiler:2.19'
Dagger2注解说明:
@Inject
Inject主要有两个作用,一个是使用在构造函数上,通过标记构造函数让Dagger2来使用(Dagger2通过Inject标记可以在需要这个类实例的时候来找到这个构造函数并把相关实例new出来)从而提供依赖,另一个作用就是标记在需要依赖的变量让Dagger2为其提供依赖。
@Provide
用Provide来标注一个方法,该方法可以在需要提供依赖时被调用,从而把预先提供好的对象当做依赖给标注了@Injection的变量赋值。provide主要用于标注Module里的方法
@Module
用Module标注的类是专门用来提供依赖的。有的人可能有些疑惑,看了上面的@Inject,需要在构造函数上标记才能提供依赖,那么如果我们需要提供的类构造函数无法修改怎么办,比如一些jar包里的类,我们无法修改源码。这时候就需要使用Module了。Module可以给不能修改源码的类提供依赖,当然,能用Inject标注的通过Module也可以提供依赖
@Component一般用来标注接口,被标注了Component的接口在编译时会产生相应的类的实例来作为提供依赖方和需要依赖方之间的桥梁,把相关依赖注入到其中。
@Scope:作用域,Dagger2通过自定义注解来限定作用域,有一个默认的作用域注解@Singleton,通常在Android中用来标记在App整个生命周期内存活的实例。也可以自定义一个@PerActivity、@PerFragment注解,用来表明实例生命周期与Activity、Fragment一致。我们可以自定义作用域的粒度(比如@PerUser等等)。
@Qualifier:限定符。当一个类的类型不足以标示一个依赖的时候,我们就可以用这个注解。例如,我们有两个@Provide注解的方法都需要一个String参数,那么在提供依赖的方法上面就可以通过自定义标识“@ForData”或者“@ForImage”来进行区别Dagger2里面已经存在一个限定符@Named注解,通过@Named(”xxxxx”)就可以进行标识。
@SubComponent:如果我们需要父组件全部的提供对象,这时我们可以用包含方式而不是用依赖方式,相比于依赖方式,包含方式不需要父组件显式显露对象(依赖方式只能拿到暴露出的实例),就可以拿到父组件全部对象。且SubComponent只需要在父Component接口中声明就可以了
@Named(@)因为Dagger2 的以来注入是使用类型推断的,所以同一类型的对象就无法区分,可以使用@Named注解区分同一类型对象,可以理解为对象的别名!
Dagger2基本使用:
创建Inject2类并使用@Inject标记构造方法,向其他类提供依赖;
创建Inject1类声明Inject2变量并使用Inject标注;
Inject1下创建show方法,调用inject2下的show方法创建InjectComponent接口使用Component标注;
创建inject方法向inject1提供依赖inject2
在Inject1的show方法中使用DaggerInjectComponent.builder().build().inject(this);获取依赖
Dagger2复杂使用:
创建ShowUtils类负责具体显示逻辑;
创建ShowInject类使用Inject标签标记ShowUtils变量引入依赖;
创建ShowModules类使用Modules标签标注管理方法中的Provides标签标注的方法并使用new关键字创建被依赖类的对象;
创建ModulesComponent接口使用@Component(modules = {ShowModules.class})
声明管理类ShowModules并创建提供依赖方法
小结
Dagger2->依赖注入框架->项目中注入类对象
->为什么使用dagger2?解耦合->在Activity不直接创建对象
基本使用:1.创建ShowInjectUtils
2.创建show方法->使用当前类下的方法
3.重写构造方法->构造方法上添加@Inject标签->当前类对象要通过dagger2注入到其他类中
4.MainActivity下编写变量使用@Inject接收注入对象
5.ShowCompont(dagger2注入对象桥梁)
6.编写抽象方法inject->声明对象注入到哪里去
7.构建项目->锤
8.调用Dagger2
进阶使用:1.创建ShowModulesInjectUtils
2.创建show方法->使用当前类下方法
3.重写构造方法->构造方法上添加@Inject标签
4.创建仓库类ShowModules->向桥梁提供对象
5.创建showProvider方法->向桥梁提供对象
6.创建桥梁
7.MainActivity下声明使用
8.构建
9.使用
public class ShowInjectUtils {
@Inject
public ShowInjectUtils() {
}
public void show(){
Log.e("####",