美文网首页
关于Dagger2的一些使用及介绍

关于Dagger2的一些使用及介绍

作者: xiaoxiage | 来源:发表于2017-03-18 16:07 被阅读0次

    Dagger2是一个Android依赖注入框架,由Google Fork 的 Square公司的Dagger基础上再开发。传统的MVC框架Activity比较臃肿,难以维护,现在主流的架构还是使用MVP(Mode + View + Presenter)的方式。但是MVP框架也有可能在Presenter中集中大量代码,引入Dagger2可以实现Presenter与Activity直接的解耦,提高模块化和可维护性。Jake Wharton 在对 Dagger 的介绍中指出,Dagger 即 DAG-er,这里的 DAG 即数据结构中的 DAG——有向无环图(Directed Acyclic Graph)。也就是说,Dagger 是一个基于有向无环图结构的依赖注入库,因此Dagger的使用过程中不能出现循环依赖。

    Dagger2

    基本特点(反射机制):

    • 没有反射,在编译时执行(图的验证、配置和预先设置)
    • 容易调试和可跟踪(具体的调用和创建堆栈)
    • 代码混淆(使用派遣方法)

    Dagger2通过注解来生成代码,定义不同角色,主要的注解有:@Inject、@Module、@Componet、@Provides、@Scope、@SubComponet等

    ​ @Inject: 通常在需要依赖的地方使用这个注解。换句话说,你用它告诉Dagger这个类或者字段需要依赖注入。这样,Dagger就会构造一个这个类的实例并满足他们的依赖。

    ​ @Module: Modules类里面的方法专门提供依赖,所以我们定义一个类,用@Module注解,这样Dagger在构造类的实例的时候,就知道从哪里去找到需要的 依赖。modules的一个重要特征是它们设计为分区并组合在一起(比如说,在我们的app中可以有多个组成在一起的modules)。

    ​ @Provides: 在modules中,我们定义的方法是用这个注解,以此来告诉Dagger我们想要构造对象并提供这些依赖。

    ​ @Component: Components从根本上来说就是一个注入器,也可以说是@Inject和@Module的桥梁,它的主要作用就是连接这两个部分。 Components可以提供所有定义了的类型的实例,比如:我们必须用@Component注解一个接口然后列出所有的   @Modules组成该组件,如 果缺失了任何一块都会在编译的时候报错。所有的组件都可以通过它的modules知道依赖的范围。
      @Scope: Scopes可是非常的有用,Dagger2可以通过自定义注解限定注解作用域。这是一个非常强大的特点,因为没必要让每个对象都去了解如何管理他们的实例。

    ​ Qualifier: 当类的类型不足以鉴别一个依赖的时候,我们就可以使用这个注解标示。例如:在Android中,我们会需要不同类型的context,所以我们就可以定义 qualifier注解“@ForApplication”和“@ForActivity”,这样当注入一个context的时候,我们就可以告诉 Dagger我们想要哪种类型的context。

    上代码

    bulid.gradle(Project)

    // Top-level build file where you can add configuration options common to all sub-projects/modules.
    
    buildscript {
        repositories {
            jcenter()
        }
        dependencies {
            classpath 'com.android.tools.build:gradle:2.2.1'
            classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
        }
    }
    
    allprojects {
        repositories {
            jcenter()
            maven { url "https://jitpack.io" }
        }
    }
    
    task clean(type: Delete) {
        delete rootProject.buildDir
    }
    

    build.gradle(Module)

    compile 'com.google.dagger:dagger:2.0.2'
    compile 'com.google.dagger:dagger-compiler:2.0.2'
    provided 'org.glassfish:javax.annotation:10.0-b28'
    

    项目结构图

    • ​本项目提供两个例子,分别是两种不同的框架注入模式 具体代码后面给链接

    • 第一种方式

      对于不同的Activity,创建各个对应的ActivityCompontent,同时把Presenter(Biz)注入到Component的视图中,这也是dagger2推荐的做法,Dagger 2希望使用@Component注解接口将依赖关系链接起来。

    Paste_Image.png

    di包下面是一些跟随Application生命周期的依赖方法与实例,其中AppModule与AppServiceModule提供了全局的Context与User类,UI包下面就是具体的MVP的代码

    Appmodule.java

    @Module
    public class AppModule {
        private final App application;
    
        public AppModule(App application) {
            this.application = application;
        }
    
        @Provides
        @Singleton
        App provideApplicationContext() {
            return application;
        }
    
    }
    

    AppServiceModule.java

    @Module
    public class AppServiceModule {
    
        @Provides
        User provideUser() {
            User user = new User();
            user.setId("1");
            user.setName("hello world");
            return user;
        }
    }
    

    Modules类里面的方法专门提供依赖

    UI下面的代码

    @ActivityScope
    @Component(modules = LoginAcivityModule.class, dependencies = AppComponent.class)
    public interface LoginActivityComponent {
    
        LoginActivity inject(LoginActivity mainActivity);
    
        LoginActivityPresenter presenter();
    }
    
    @Module
    public class LoginAcivityModule {
    
        private LoginActivity mLoginActivity;
    
        public LoginAcivityModule(LoginActivity loginActivity) {
            this.mLoginActivity = loginActivity;
        }
    
    
        @Provides
        @ActivityScope
        LoginActivity provideMainActivity() {
            return mLoginActivity;
        }
    
    
        @Provides
        @ActivityScope
        LoginActivityPresenter provideMainActivityPresenter(LoginActivity loginActivity, User user) {
            return new LoginActivityPresenter(loginActivity, user);
        }
    }
    
    public class LoginActivityPresenter {
    
        private LoginActivity mainActivity;
        private User user;
    
        public LoginActivityPresenter(LoginActivity mainActivity, User user) {
            this.mainActivity = mainActivity;
            this.user = user;
        }
    
    
        public void showUserName() {
            System.out.println(user.getName());
            mainActivity.setUserName(user.getName());
        }
    }
    

    到这注入初步就可以了。

    使用:

    public class LoginActivity extends BaseActivity {
    
        private TextView mytext;
    
        @Inject
        LoginActivityPresenter presenter;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            mytext = (TextView) findViewById(R.id.mytext);
    
            presenter.showUserName();
    
        }
    
        @Override
        protected void setupActivityComponent(AppComponent appComponent) {
            DaggerLoginActivityComponent.builder()
                    .appComponent(appComponent)
                    .loginAcivityModule(new LoginAcivityModule(this))
                    .build()
                    .inject(this);
        }
    
        public void setUserName(String userName){
            mytext.setText(userName);
        }
    
    
    }
    

    Dagger生成的代码

    • 这里只介绍LoginActivity,AppComponent生成是一样的。

    • DaggerLoginActivityComponent.build会创建LoginActivity_MembersInjector,LoginActivity_MembersInjector会为LoginActivity的所有注入成员提供依赖,只要调用inject(),就能获取所需的字段和依赖。

    • 在引用inject的时候,Dagger会为我们生成,上面的例子则会生成LoginAcivityModule_ProvideMainActivityPresenterFactory的工厂,这个工厂实现就是创建了LoginActivityPresenter的实例。

    Paste_Image.png
    • DaggerLoginActivityComponent类,我们有一个Provider,它不仅仅是一个提供实例的接口,它还是被ScopedProvider构造出来的,可以记录创建实例的范围。

    end

    到此Dagger2的简单使用就差不多了,另外还有一种MVP方式结合的Dagger2例子,第二个例子是没有将Presenter是注入到Component中的,好处就是节省了代码。下面给出例子源码链接

    源码

    https://github.com/xiahao2014/Dagger2MVP

    相关文章

      网友评论

          本文标题:关于Dagger2的一些使用及介绍

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