【MVP+retrofit+rxAndroid+dagger2】读易读应用框架笔记(三)完结篇

  本文旨在学习MVP+retrofit+rxAndroid(rxJava)+dagger2框架,已经争取到作者的支持,作者的github地址是:https://github.com/laotan7237/EasyReader,作者原csdn地址是:http://blog.csdn.net/laotan7237/article/details/68946797,感谢作者的支持!

  现在我们已经将retrofit2+rxJava异步请求和响应式框架了解清楚了,接下来我们要探究最后也是最为复杂的依赖注入框架dagger2,在前面我们看到代码里LoadingBaseActivity中持有的T泛型的mPresenter上有一个@Inject@注解,这个注解我们在MovieDetaiPresenterImpl当中也看到了构造方式上有一个对应的@Inject,除此外inject这个package下面还有其他的很多内容帮助我们实现依赖注入,具体而言,DoubanMovieDetailPresenterImpl当中的DoubanService的实例化方式这套机制到底是如何运行的,使我们想要理解的问题。

dagger2的基础知识包括几个@注解,@Inject@component@Provides@Module@Scope@Qualifier@Inject分别写在需要注入的类实例和该类的某个构造方法上,dagger在需要实例化的地方(如在Activity里)去找对应的这个类里也带有@Inject注解的构造方法,帮助你构造这个实例,这种方式与Butterknife@Bind类似。

以阅读的代码为例,我们分析LoadingBaseActivity中看到了对继承自BasePresenter的泛型T实例mPresenter上方有一个@Inject,这意味着针对每一个指定了T泛型的LoadBasePresenter实例会在项目中去寻找同样注解了@Inject的提供T类型的构造方法,找到后,自动将T型实例构造出来,我们分析的DoubanMovieDetail中,T被指定为MovieDetailPresenterImpl,我们确实的再这个类的构造方法上看到了@Inject注解。我们容易想到,针对同一个类的实例可能在不同的地方要使用不同的构造方法,这时候dagger要怎么确定使用哪一个构造,这个问题是dagger已经想到并且解决了的,dagger将它称作“注入迷失”,后面我们用到的@Scope@Qualifier能够解决构造方法的选择问题,并能够为注入方式做一些限定,譬如构造出单例。

最难理解但最常见的注解是@Component@Provides@Module”这一组,使用@Module注解的类里定义需要实例化对象的提供方法,使用provide作为方法名的起始,这样dagger在识别到这些方法的时候会去创建相应的工厂方法,在这些方法名上我们采用@Provides注解,表明方法返回类型的对象由该方法实例化,将@Module注解的类注入到需要使用的地方是@Component@component注解接口,在注解处申明需要注入到目标类里的Module,语法格式为@Component(mudules={XXXModule.class}),接口中定义接口方法inject,这个方法在需要注入的地方被调用。

@Singleton
@Component(modules = { DoubanHttpModule.class})
public interface MovieDetailComponent {
    void injectMovieDetail(MovieTopDetailActivity movieTopDetailActivity);
}

public class MovieTopDetailActivity extends LoadingBaseActivity<DoubanMovieDetailPresenterImpl> implements DoubanMovieDetailPresenter.View

@Override
protected void initInject() {
    DaggerMovieDetailComponent.builder()
            .doubanHttpModule(new DoubanHttpModule())
            .build().injectMovieDetail(this);
}

我们分析的代码中MovieTopDetailActivity中调用了该方法用于注入MovieDetailConponent当中所包含的Module

我们在MovieTopDetailActivity中看到他是继承自持有DoubanMovieDetailPresenterImpl类型mPresenterLoadingBaseActivity,在DoubanMovieDetailPresenterImpl里持有一个DoubanService实例,但是可以看到这个Service没有被new的方式实例化,这里的Service是依靠注入的方式由dagger帮我们实例化的,这里我们理解一下“Component类似于一个注射器,把Module注入到使用的地方去”,在initInject这个方法里我们使用ComponentDaggerMovieDetailComponent是有Dagger自动生成的,生成标准是有@Component注解)将DoubanHttpModule注入到this(这个Activity)当中,在DoubanHttpModule有一个provideDoubanService方法,这代表着所有我们需要用到DoubanService的时候dagger都会调用这个方法帮我们构造一个实例来,可以注意到,在构造这个Service的实例时传入的参数Retrofit实例也是由dagger帮助我们实例化的,使用provideDoubanRetrofit方法,这里我们看到了一个@注解——@DoubanUrl,跟进去后我们发现这是一个@Qualifier注解,这个注解帮助dagger找到具体对应的实例构造方法,这里需要传入的Retrofit对象必须保证是由DoubanService.API_DOUBAN这个url作为参数构造的,需要与其他的Retrofit对象区分开来(在其他的Module里有很多类型的Retrofit对象),可以利用在使用处和构造方法处分别添加同一个@注解(@Qualifier类型),来防止注入迷失。

@Module
public class DoubanHttpModule extends BaseHttpModule {

    @Singleton
    @Provides
    @DoubanUrl
    Retrofit provideDoubanRetrofit(Retrofit.Builder builder, OkHttpClient client) {
        return createRetrofit(builder, client, DoubanService.API_DOUBAN);
    }

    @Singleton
    @Provides
    DoubanService provideDoubanService(@DoubanUrl Retrofit retrofit) {
        return retrofit.create(DoubanService.class);
    }

}

@Qualifier
@Documented
@Retention(RUNTIME)
public @interface DoubanUrl {
}

@Qualifier类型的注解中,需要指定@Qualifier@Documented@Retention(RUNTIME)这三项内容。

未完待续

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值