Dagger2 简单入门三部曲(三)——怎么使用?

Dagger2 简单入门三部曲(一)——是什么?
Dagger2 简单入门三部曲(二)——为什么使用?
Dagger2 简单入门三部曲(三)——怎么使用?

直接导入依赖包即可使用

Android 的使用方式:在 app 的 build.gradle 下添加如下代码即可

implementation 'com.google.dagger:dagger:2.16'
annotationProcessor 'com.google.dagger:dagger-compiler:2.16'

使用【倒推方法】学习如何使用

推荐去看前面两篇博文的代码,在这里会容易理解一些。

下面是在使用了接口注入的方式实现了依赖注入,最后调用的代码:

MovieFinder movieFinder = new MovieFinderImpl();
MovieLister movieLister = new MovieLister();
// 这里通过接口注入
movieLister.injectFinder(movieFinder);
movieLister.moviesDirectedBy("张艺谋");

Dagger2 也是使用依赖注入的方法,那么如何去掉 new 这些操作?
最原始没有使用依赖注入方式的调用如下:

MovieLister firstMovieLister = new MovieLister();
firstMovieLister.moviesDirectedBy("张艺谋");

具体实现是通过 MovieLister 构造函数中绑定了 MovieFinderImpl对象,如下:

MovieFinder moviewFinder
public MovieLister() {
    moviewFinder = new MovieFinderImpl();
}

最后在 moviesDirectedBy 方法中通过 findAll方法 查找,如下:

moviewFinder.findAll();

以上代码在MovieLister中要关心MovieFinderImpl的实现,如果MovieFinderImpl的构造函数修改了,我们在MoviewLinster中也要修改,所以这块就出现了耦合。

在我们理解了接口注入的方式之后,通过接口注入方式实现解耦,调用如下:

MovieFinder movieFinder = new MovieFinderImpl();
MovieLister movieLister = new MovieLister();
// 这里通过接口注入
movieLister.injectFinder(movieFinder);
movieLister.moviesDirectedBy("张艺谋");

在这里不管MovieFinderImpl的如何修改,都不会去动MovieLister,我们只要在调用接口注入的地方修改即可,在以后的修改也可以很清晰明确的定位到。

但是这里也有一点问题,每次都要new对象,每次都要给对象分配控件,这不是很好的办法。于是出现了 Dagger2

在使用了 Dagger2实现依赖注入之后的调用如下:

movieLister = DaggerInJectMovieLister.create().getMoviewLister();
movieLister.moviesDirectedBy("张艺谋");

那么Dagger2 是如何去掉 new 这些操作?(不讲原理,,还没学透讲不明白,只讲实现)

在第二个实现方式接口注入中,是需要 new MovieFinderImpl() 那么现在只需要这样MovieFinderImpl的构造函数中添加@Inject,同时在MovieFinderInterface接口中添加@Component即可,

这么操作就把new MovieFinderImpl()给去掉了,代码如下:

第一步:
public class MovieFinderImpl implements MovieFinder {

    private static final String TAG = "MovieFinderImpl";

    // 这里使用了 @Inject 注解
    @Inject
    public MovieFinderImpl() {}


    @Override
    public List findAll() {
        Log.e(TAG, "findAll: ============" );
        return new ArrayList();
    }

    @Override
    public List findAll(String dbName) {
        Log.e(TAG, "findAll: ============"+dbName );
        return new ArrayList();
    }
}

第二步:
// 这里使用 @Component 注解
@Component
public interface MovieFinderInterface {
    // MovieFinderImpl 是 @Inject 绑定的对象
    MovieFinderImpl getMoviewFinder();
}

接口注入方式中还需要 new MovieLister() ,现在只需要这样MovieLister的构造函数中添加@Inject,同时在MovieListerInterface接口中添加@Component即可,这么操作就把new MovieLister()给去掉了,代码如下:

第一步:
public class MovieLister implements MovieListerInterface{

    private static final String TAG = "MovieLister";
    private MovieFinderImpl moviewFinder;

     // 这里使用了 @Inject 注解
    @Inject
    public MovieLister() {}

    @Inject
    public void funTest() {
        Log.e(TAG, "funTest: Inject" );
    }
  

    @Override
    public Movie[] moviesDirectedBy(String arg) {
        moviewFinder = DaggerMovieFinderInterface.create().getMoviewFinder();
        List allMovies = moviewFinder.findAll();
        Log.e(TAG, "moviesDirectedBy: ---->"+arg );
        return (Movie[]) allMovies.toArray(new Movie[allMovies.size()]);
    }

    @Override
    public Movie[] moviesDirectedBy(String arg, String dbName) {
        List specialMovies = moviewFinder.findAll(dbName);
        Log.e(TAG, "moviesDirectedBy: ---->"+arg +"======="+dbName);
        return (Movie[]) specialMovies.toArray(new Movie[specialMovies.size()]);
    }
}

第二步:
// 这里使用 @Component 注解
@Component
public interface InJectMovieLister {
    // MovieLister 是 @Inject 绑定的对象
    MovieLister getMoviewLister();
}


通过上面的例子可以看出 @Inject@Component之间是桥接的,也就是通过@Inject绑定了对象,然后通过@Component注解接口,返回该对象。

文章就到这了。有问题欢迎私信一起学习。

日更第七天,日更真的挺考验人的。

    原文作者:_龙衣
    原文地址: https://www.jianshu.com/p/11f803ec702c
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞