煎饼

煎饼为你分享Android有关的技术文章
不断分享,点滴积累,共同提高

关注微信公众号[developers]
更快的了解新的技术动态

Dagger on Android-Dagger1介绍

接着上篇文章Dagger on Android-基础篇继续讲解,这篇来继续说说Dagger1.如果你没有看过我之前的博文Android 依赖注入:Dagger 实例讲解(Demo下载),还是建议去看看,里面通过一个Java的例子来讲解了如何使用以及一些关键点,相信对你理解Dagger也会有一定帮助。本文会通过一个Android的Demo来介绍Dagger1.

引入Dagger1

1
2
3
4
dependencies {
    compile 'com.squareup.dagger:dagger:1.2.2'
    provided 'com.squareup.dagger:dagger-compiler:1.2.2'
}

第一个是Dagger library,第二个library是Dagger compiler,它会在编译时创建注入依赖所需要的类,这种方式可以避免使用过多的反射。使用provided表示在编译的时候用到这个library,不会被应用使用,所以它不会被编译到最终的APK中去。

创建第一个Module

Module在Dagger中可以说是必须的,你要明白它的意思及功能。Modules是为我们提供注入所需要的实例化对象的类。

在App中,我的习惯是先创建一个AppModule,提供全局所需要的一些类的实例化对象,如 Applicationcontext。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
@Module(
        injects = {
                App.class
        }
)
public class AppModule {
    private App app;
    public AppModule(App app) {
        this.app = app;
    }
    @Provides 
    @Singleton 
    public Context provideApplicationContext() {
        return app;
    }
}

@Module: 表明这个类是一个Dagger module

injects: 表明这个module所要注入的类,我们还说明这类想会被直接注入ObjectGraph,这点下面会说。

@Provides: 表明这个方法是注入的提供者(injection provider).方法的名称是什么不重要,关键是返回的类型。

@Singleton: 使用了Singleton注解的方法总是会返回相同的实例化对象,这种方式比平时用的单例模式要好很多。每次注入,我们不会得到一个新的实例对象,而是返回一个已经存在,同时也解释了provider的作用。Application 对象是唯一的。

我们再创建另一个module,命名为DomainModule.在App的每一个结构层创建至少一个module是十分有帮助的。DomainModule会提供一个analytics manager,在App启动的时候会弹出一个toast。在实际的项目中,这个manager可能是其他analytics服务像Umeng Analytics。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
@Module(
        complete = false,
        library = true
)
public class DomainModule {
    @Provides
    @Singleton 
    public AnalyticsManager provideAnalyticsManager(Application app){
        return new AnalyticsManager(app);
    }
}

compelte = false 表示这个module是不完整的,我们说在一个module中的一些依赖需要通过另一个module来提供。在这个列子中provideAnalyticsManager方法所需参数Application对象来自于AppModule(下面的includes处理这种关系)。当在某个类中通过下面注入使用AnalyticsManager时,Dagger会调用此方法,也会检测所需要的其他依赖,Application会被从ObjectGraph中请求到。

1
2
@Inject
AnalyticsManager mAnalyticsManager;

library = true 因为Dagger compiler会检测 AnalyticsManager 还没有被它自己或者它所注入的类使用。它行为就是AppModule的一个library module。

在AppModule中它包括DomainModule:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
@Module(
        injects = {
                App.class
        },
        includes = {
                DomainModule.class
        }
)
public class AppModule {
...
}

创建ObjectGraph

看过直接介绍Dagger的可能对ObjectGraph有一定了解。所有的依赖关系都存在于ObjectGraph中,它包含所有已经创建的实例并且可以将它们注入到我们向它添加的对象中。

在DomainModule中,我们看到了常用的依赖注入,通过构造器传入依赖。但是在Android中的一些类,我们不能控制构造器,所以需要其他的方式来实现依赖的注入。

在App类中创建ObjectGraph并被注入到此类中已得到它所有的依赖。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
public class App extends Application {

    private ObjectGraph objectGraph;
    @Inject 
    AnalyticsManager analyticsManager;

    @Override 
    public void onCreate() {
        super.onCreate();
        objectGraph = ObjectGraph.create(getModules().toArray());
        objectGraph.inject(this);
        analyticsManager.registerAppEnter();
    }

    private List<Object> getModules() {
        return Arrays.<Object>asList(new AppModule(this));
    }
}

使用@Inject注解将AnalyticsManager注入到App类中,这个filed必须是public或者默认的范围(scoped),以使Dagger能分派它们。还创建了一个modules list(仅有一个module,DomainModule包含在AppModule中)和 一个ObjectGraph对象,之后我们注入App。objectgraph.inject(this)被调用之后,objectgraph所包含的依赖也被注入,所以我们可以调用AnalyticsManager的方法。

总结

现在,关于Dagger1的基本内容已经介绍完了,看过我之前博文的同学可能发现还有一些内容像Lazy injections,provider injections等没有介绍。不是我不讲,而是在你没有本文上面这些内容之前,我本人不建议去了解研究它们。

872

分享本文:

Dagger on Android-从Dagger1到Dagger2