美文网首页程序员
Dagger2 Android --- 基础使用篇

Dagger2 Android --- 基础使用篇

作者: bf027edd3b22 | 来源:发表于2018-10-18 16:48 被阅读59次

该文章默认你已经掌握了Dagger2的常规使用。

如果对Dagger2的概念还不是很清楚,可以参考:

Dagger Android产生的原因??

  1. 对象使用者如果需要使用 Inject 注解生成的对象,需要知道其注入器(比如:DaggerxxxComponent),它打破了依赖注入的原则:一个类不应该知道如何注入它。
  2. 随着项目代码的增多,类似 DaggerxxxComponent.buider().build().inject() 这样的模板代码也会越来越多,使得后期很难重构。

Dagger2 2.1x新特性

解决了Dagger2 2.10之前的两个明显的缺陷,被注入者不需要知道其注入者

依赖

//dagger2 依赖
implementation 'com.google.dagger:dagger:2.16'
//dagger2 android依赖,一般直接依赖dagger-android-support,其内部默认依赖了dagger-android
//implementation 'com.google.dagger:dagger-android:2.16'
//添加了android support的支持
implementation 'com.google.dagger:dagger-android-support:2.16'
//dagger注解处理器
annotationProcessor 'com.google.dagger:dagger-compiler:2.16'
//dagger android注解处理器 
annotationProcessor 'com.google.dagger:dagger-android-processor:2.16'

使用步骤

1. 被依赖类:在构造函数上使用@Inject注解声明
    public class Student {
    
        private String name;
    
        @Inject
        public Student() {
    
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
        
    }
2. 使用依赖对象
    public class MainActivity extends AppCompatActivity {
    
        private static final String TAG = MainActivity.class.getSimpleName();
    
        @Inject
        Student student;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            
            Log.e(TAG, "student ---- " + student.toString());
        }
    }

如果直接这样运行肯定是直接NullPoint,因为student还没有被注入到MainActivity之中。

那Student对象又是如何注入的呢?

3. 实现依赖对象和使用者的绑定
  1. 自定义Application继承DaggerApplication(注意导包,使用dagger.android.support.DaggerApplication)

    这一步是实现自动注入的前提

     public class DemoApp extends DaggerApplication {
         
         @Override
         protected AndroidInjector<? extends DaggerApplication> applicationInjector() {
             return null;    //这里先暂时返回null
         }
     }
    
  2. 我们知道需要将对象注入到使用者之中,要通过Component,那我们先创建MainComponent,使用@SubComponent注解(为什么是使用SubComponent呢??)

     @Subcomponent
     public interface MainComponent extends AndroidInjector<MainActivity> {
     
         @Subcomponent.Builder
         abstract class Builder extends AndroidInjector.Builder<MainActivity>{}
     
     }
    

    这段代码是模板代码,只需要修改AndroidInjector<T>中的泛型,改成需要注入的对象,也就是MainActivity

  3. 有了MainComponet,就需要将其注入到MainActivity之中

    2.10之前,是通过这行代码DaggerMainComponet.builder().build().inject(this);实现的。

    现在Dagger2会帮我们自动实现注入,但是需要告诉Dagger2哪些Activity需要被注入。

    新建ActivityBindingModule类:

     @Module(subcomponents = {MainComponent.class})
     public abstract class ActivityBindingModule {
     
         @Binds
         @IntoMap
         @ActivityKey(MainActivity.class)
         abstract AndroidInjector.Factory<? extends Activity> bindMainActivityInjectorFactory(MainComponent.Builder builder);
     
     }
    

    可以看到,这个module里面依赖了MainComponent,所以MainComponent需要使用@SubComponet注解,注入的代码也是通过MainComponent中的抽象方法 Builder 生成的。

    上面这段代码的作用:生成Map<Activity.class, AndroidInjector.Factory<? extends Activity>>的map,并将MainActivity的注入器放入其中。

  4. 创建AppComponent, 在modules中添加 AndroidSupportInjectionModule.class, ActivityBindModule.class,执行make project

     @Component(modules = {AndroidSupportInjectionModule.class, ActivityBindModule.class})
     public interface AppComponent extends AndroidInjector<DemoApp> {
     
         @Component.Builder
         abstract class Builder extends AndroidInjector.Builder<DemoApp>{
     
         }
     }
    
  5. make完成后会生成DaggerAppComponent类,在DemoApp中返回

     @Override
     protected AndroidInjector<? extends DaggerApplication> applicationInjector() {
         return DaggerAppComponent.builder().create(this);
     }       
    
  6. 最后在MainActivity中添加 AndroidInjection.inject(this);

     public class MainActivity extends AppCompatActivity {
     
         @Inject
         Student student;
     
         @Override
         protected void onCreate(Bundle savedInstanceState) {
             super.onCreate(savedInstanceState);
             AndroidInjection.inject(this);
             setContentView(R.layout.activity_main);
             Log.e(TAG, "student ---- " + student.toString());
         }
     }   
    

    这一步也可以通过修改Acitivty的基类,省略

     public class MainActivity extends DaggerActivity{
         ...
     }
     
     //在DaggerActivity的源码中,可以看到内部已经我们添加了这行代码
     @Beta
     public abstract class DaggerActivity extends Activity implements HasFragmentInjector {
     
       @Inject DispatchingAndroidInjector<Fragment> fragmentInjector;
     
       @Override
       protected void onCreate(@Nullable Bundle savedInstanceState) {
         AndroidInjection.inject(this);
         super.onCreate(savedInstanceState);
       }
     
       @Override
       public AndroidInjector<Fragment> fragmentInjector() {
         return fragmentInjector;
       }
     }
    

上面就是完整的注入流程,所有的模板代码Dagger Android都已经帮我们处理好了,我们需要做的只是处理依赖注入关系。

大致的流程:

image

但是这么多步骤,难免会产生错误,而且学习成本也增加了很多,好在Dagger2 2.11之后新增了@ContributesAndroidInjector简化了注入过程(这个后面分析)。

注解&注入流程分析

相关文章

网友评论

    本文标题:Dagger2 Android --- 基础使用篇

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