美文网首页
Dagger2基本整体使用讲解--第二章

Dagger2基本整体使用讲解--第二章

作者: 沪漂意哥哥 | 来源:发表于2022-05-26 22:03 被阅读0次

首先看一张图

image.png

举个例子,比如说我通过@Inject去创建一个对象,而这个对象的不是我们能编写的(例如系统的,jar包提供的),我们就不能用@Inject方式来创建这个对象
例如:

@Inject
public TextView textView;

TextView是android库中的,我们没办法用@Inject去注解构造方法,这下改怎么办呢?

上面图就是解决这个的办法

下面解释下:

  • Compenent第一章节的时候说过,连接器,他是连接Module和Container的桥梁,我第一章节就说了只有在调用了连接器的的方法,这个对象才开始创建

  • Module 提供创建对象的方法

  • Container需要创建对象的,例子中就Activity

解决上面的问题

  • 创建Module(供给类,告诉创建TextView,怎么创建)
//提供对象的Module
@Module
public class TestModule {

   //为啥需要这个呢,因为provideTextView需要Context做行参,我们当然也要提供一个获取Context的方法啊
   @Provides
   public Context provideContext(){
       //这是一个全局的Application
       Log.d("wyz","执行了:provideContext()");
       return App.application;
   }

   //必须使用 @Provides 告诉Compenent 这是一个供给方法 这里我要提供一个TextView
   @Provides
   public TextView provideTextView(Context context){
       // 这里需要一个上下文,我先写null,后期提供方案
       TextView textVie=new TextView(context);
       Log.d("wyz","执行了:provideTextView()创建TextView:"+textVie.hashCode());

       return textVie;
   }
} 
  • 创建连接器
//告诉Component的modules,可以看出是一个数组,所以可以提取多个
//    重要的事情说三遍 接口 接口 接口
@Component(modules = {TestModule.class})
public interface TestCompenent {
   void inject(MainActivity mainActivity);//提供链接方法
} 
  • Build下,生成那个连接器的类,编写MainActivity
public class MainActivity extends AppCompatActivity {

   @Inject
   public TextView textView;

   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       DaggerTestCompenent.create().inject(this);
       textView.setText("Dagger2");
       log("大吉大利,我没崩溃textView:"+textView.hashCode());
   }

   public void log(String value){
       Log.d("wyz", value);
   }
} 

运行结果

04-18 18:13:24.247 31407-31407/com.example.wenyingzhi.myapplication D/wyz: 执行了:provideContext()
04-18 18:13:24.252 31407-31407/com.example.wenyingzhi.myapplication D/wyz: 执行了:provideTextView()创建TextView:213786299
04-18 18:13:24.252 31407-31407/com.example.wenyingzhi.myapplication D/wyz: 大吉大利,我没崩溃textView:213786299

注意到了吗?2个TextView的HashCode是一样哦,所以是一个对象

分析过程

  • 当我们调用DaggerTestCompenent.create().inject(this);连接器的方法后

  • 会看当前类需要@Inject注解的对象,寻找构造方法,有没有通过@Inject注解,发现没有

  • 去Compenent关联的Modules中找@Provides注解的方法,并且是返回TextView的方法,看方法参数需要Context

  • 再去Compenent关联的Modules中找@Provides注解的方法,并且是返回Context的方法

  • 然后按个调用,就完成了一个对象的初始化操作,总之就是你要初始化对象关联的对象,参数都必须能找到,2种方式Module中找到或者类的本身使用了@Inject

下面来个整体的demo

public class Teacher {
   public Student student;
   public StudentClass studentClass;

   @Inject
   public Teacher(Student student, StudentClass studentClass) {
       this.student = student;
       this.studentClass = studentClass;
   }
} 
@Module
public class TeacherModule {
   @Provides
   public Student provideStudent(){
       return new Student();
   }

   @Provides
   public StudentClass provideStudentClass(){
       return new StudentClass();
   }
} 
@Component(modules = {TeacherModule.class})
public interface TeacherCompenent {
   void inject(MainActivity mainActivity);
}

因为Teacher的构造方法我通过了@Inject注解所以,不需要再Module处定义@Provide,同理如果我的Student或StudentClass类的构造方法也@Inject注解了,Module中也不需要提供@Provide

public class Student {
   @Inject
   public Student() {
   }
}

那么Module中就不再需要定义 provideStudent()方法

@Module
public class TeacherModule {

   @Provides
   public StudentClass provideStudentClass(){
       return new StudentClass();
   }
} 

相关文章

网友评论

      本文标题:Dagger2基本整体使用讲解--第二章

      本文链接:https://www.haomeiwen.com/subject/lihpprtx.html