美文网首页Android-Dagger2Android知识Android开发
Dagger2源码分析-最简单的注入过程

Dagger2源码分析-最简单的注入过程

作者: 越小河流域 | 来源:发表于2016-09-22 11:52 被阅读462次
    Dagger要实现的类以及APT生成的类

    Dagger2最简单的依赖注入实践

    要实现三个类:

    1. Dagger2Activity
    • ActivityComponent
    • ActivityModule

    直接上代码:

    1、Dagger2Activity

    public class Dagger2Activity extends Activity {
    
        private ActivityComponent mActivityComponent;
    
        @Inject
        UserModel mUserModel;
    
        @Bind(R.id.tv_user_id)
        TextView tvUserId;
        @Bind(R.id.tv_user_name)
        TextView tvUserName;
        @Bind(R.id.tv_user_gender)
        TextView tvUserGender;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.ex_dagger2_activity);
            ButterKnife.bind(this);
    
            mActivityComponent = DaggerActivityComponent.builder().activityModule(new ActivityModule(1, "Leon", 1)).build();
            mActivityComponent.inject(this);
    
            tvUserId.setText(mUserModel.id + "");
            tvUserName.setText(mUserModel.name);
            tvUserGender.setText(mUserModel.gender + "");
        }
    }
    

    2、ActivityComponent

    @Component(modules = ActivityModule.class)
    public interface ActivityComponent {
    
        void inject(Dagger2Activity activity);
    }
    

    3、ActivityModule

    @Module
    public class ActivityModule {
    
        private UserModel mUserModel;
    
        public ActivityModule(long userId, String userName, int gender) {
            mUserModel = new UserModel(userId, userName, gender);
        }
    
        @Provides
        UserModel provideUserModel() {
            return mUserModel;
        }
    }
    

    列出所有类

    使用Dagger,要实现
    Dagger2ActivityActivityComponentActivityModule
    三个类,Make Project之后生成三个类:

    • DaggerActivityComponent
    • Dagger2Activity_MemberInject
    • ActivityModule_ProviderUserModelFactory

    分析代码

    注入程序的入口

    mActivityComponent.inject(this);
    
    @Component(modules = ActivityModule.class)
    public interface ActivityComponent {
    
        void inject(ExDagger2Activity activity);
    }
    

    直接调用的是ActivityComponent的inject。ActivityComponent是个接口,实现类是DaggerActivityComponent。

      @Override
      public void inject(ExDagger2Activity activity) {
        exDagger2ActivityMembersInjector.injectMembers(activity);
      }
    

    注意,inject接收被注入的实例参数。接下来的DaggerActivityComponent的注入工作应该是:

    • 找到被注入的Activity中被@Inject注解的成员mUserModel变量;
    • 然后赋值给mUserModel

    DaggerActivityComponent有两个成员变量:

    private Provider<UserModel> provideUserModelProvider;//负责提供对象
    private MembersInjector<ExDagger2Activity> dagger2ActivityMembersInjector;//负责给被@Inject的成员变量赋值
    

    赋值给被@Inject的成员变量

    DaggerActivityComponent的inject调用的是dagger2ActivityMembersInjector的injectMembers,实现如下:

    Dagger2Activity_MembersInjector.java

      @Override
      public void injectMembers(ExDagger2Activity instance) {
        if (instance == null) {
          throw new NullPointerException("Cannot inject members into a null reference");
        }
        instance.mUserModel = mUserModelProvider.get();
      }
    

    从mUserModelProvider中获取对象赋值给被注入类Dagger2Activity的mUserModel成员变量(所以,mUserModel必须是public的)。

    mUserModelProvider从哪里来的?

    DaggerActivityComponent.java

      private void initialize(final Builder builder) {
    
        this.provideUserModelProvider =
            ActivityModule_ProvideUserModelFactory.create(builder.activityModule);
    
        this.exDagger2ActivityMembersInjector =
            ExDagger2Activity_MembersInjector.create(provideUserModelProvider);
      }
    

    DaggerActivityComponent初始化他的两个成员变量时,传入的。也就是说,赋值提供对象的是provideUserModelProvider(看名字也知道了)。

    轮到ActivityModule发挥作用了:创建对象

    ActivityModule生成了一个工厂类ActivityModule_ProvideUserModelFactory。这个工厂类是专门生产UserModel对象的。

    @Module
    public class ActivityModule {
    
        private UserModel mUserModel;
    
        public ActivityModule(long userId, String userName, int gender) {
            mUserModel = new UserModel(userId, userName, gender);
        }
    
        @Provides
        UserModel provideUserModel() {
            return mUserModel;
        }
    }
    
    @Generated(
      value = "dagger.internal.codegen.ComponentProcessor",
      comments = "https://google.github.io/dagger"
    )
    public final class ActivityModule_ProvideUserModelFactory implements Factory<UserModel> {
      private final ActivityModule module;
    
      public ActivityModule_ProvideUserModelFactory(ActivityModule module) {
        assert module != null;
        this.module = module;
      }
    
      @Override
      public UserModel get() {
        return Preconditions.checkNotNull(
            module.provideUserModel(), "Cannot return null from a non-@Nullable @Provides method");
      }
    
      public static Factory<UserModel> create(ActivityModule module) {
        return new ActivityModule_ProvideUserModelFactory(module);
      }
    }
    

    放在一起对比。ActivityModule的provideUserModel方法创建了对象,被ActivityModule_ProvideUserModelFactory的get方法获取。

    总结

    分析完代码之后,再看看文章开头的类图。Make Project之后生产三个类的作用分别是:

    • DaggerActivityComponent:程序入口,负责串联创建对象与赋值。
    • Dagger2Activity_MemberInject:持有被注入的对象DaggerActivity,赋值给被@Inject的成员变量。
    • ActivityModule_ProviderUserModelFactory:创建对象。

    相关文章

      网友评论

        本文标题:Dagger2源码分析-最简单的注入过程

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