Dagger2使用简介

Dagger2使用简介

Dagger是最早由Square公司开发的一款开源的依赖注入工具(Dagger1, 版本1.x),现在由Google接手进行开发和维护(Dagger2, 版本2.x)。Dagger2相比于Dagger1有不少改动的地方,效率更高,本文将通过Demo讲解Dagger2的用法。

本文Github源码下载

在Demo的两个分支(without_dagger_branch、with_dagger_branch)上分别通过自定义依赖,以及使用Dagger2进行依赖注入的方式实现了相同的功能,通过两种方式的比较可以加深理解。

Demo利用RecyclerView实现了一个简单的电影列表,效果如下:
Demo效果

首先理解什么是依赖,看without_dagger_branch的代码如下:

public class MainActivity extends AppCompatActivity {    
    ...
    private RecyclerViewAdapter viewAdapter;   

    @Override    
    protected void onCreate(Bundle savedInstanceState) {  
        ...            
        viewAdapter = new RecyclerViewAdapter(this);        

        mRecyclerView.setAdapter(viewAdapter);      
        ...  
  }
    ...
}

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {  
    ...  
    private ThirdPartyUtility utility;    
    public RecyclerViewAdapter(Context context) {        
        this.context = context;        
        this.utility = new ThirdPartyUtility(context);    
    }
    ...
}

在MainActivity里用到了RecyclerViewAdapter类型的变量viewAdapter,其中RecyclerViewAdapter是我们自定义的RecyclerView的Adapter,而RecyclerViewAdapter里又用到了ThirdPartyUtility类型的变量utility,ThirdPartyUtility是第三方开发的工具包。viewAdapter就称为类MainActivity的依赖,而utility称为类RecyclerViewAdapter的依赖。

像上面代码所示的这种方式,在类里面进行用到的变量的初始化,就是传统的初始化依赖的方式。通过依赖注入框架,我们可以将依赖初始化的过程放在Dagger辅助类里面完成,然后注入到MainActivity中,这样一来方便测试,同时可以使得MainActivity里面的代码聚焦于功能逻辑的实现,而不是各种变量繁杂的初始化。

切换到with_dagger_branch分支,我们通过Dagger进行依赖注入实现同样的功能。Dagger依赖注入主要是通过几个注解实现的,包括@Inject, @Module,@Provides,@Component等。

使用Dagger前先配置一下gradle:
根目录gradle:

buildscript {    
    ...
    dependencies {   
        ...     
        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'        
    }
    ...
}

App目录下gradle:

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

配置完Gradle,sync一下,开始开发。首先使用@Inject指定要注入的变量:

public class MainActivity extends AppCompatActivity {      
    ...
    @Inject    
    RecyclerViewAdapter viewAdapter; 
   
    @Override    
    protected void onCreate(Bundle savedInstanceState) {        
        ...
        mRecyclerView.setAdapter(viewAdapter);
        ...        
}

通过用@Inject指定要注入的依赖变量viewAdapter,我们无需再通过new的方式进行变量初始化。

接下来修改RecyclerViewAdapter类,给其构造函数添加@Inject注解,告知Dagger利用哪个函数进行依赖viewAdapter的初始化:

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {    
    ...   
    @Inject    
    ThirdPartyUtility thirdPartyUtility;    
    @Inject    
    Context context;  
  
    @Inject    
    public RecyclerViewAdapter() {}
    ...
}

在RecyclerViewAdapter中,我们用到两个变量thirdPartyUtility和context,同理,我们通过添加@Inject注解实现这两个变量的依赖注入。这里有个问题,跟我们自定义的RecyclerViewAdapter类不同,Context类和ThirdPartyUtility不是我们自定义的类,不受我们的控制,所以我们无法也在它们的构造函数中添加@Inject注解来告知Dagger怎样进行初始化。这里就需要用到@Module注解和@Provides注解来应对这种情况。

新定义一个类ModuleClass,如下:

@Module
public class ModuleClass {    
    private final Context context;    
    public ModuleClass(Context context) {        
        this.context = context;    
    }    

    @Provides    
    Context provideContext() {        
        return context;    
    }    

    @Provides    
    ThirdPartyUtility provideThirdPartyUtility() {        
        return new ThirdPartyUtility(context);    
    }
}

给ModuleClass添加@Module注解,并添加两个以provide作为前缀的函数,分别提供第三方类Context和ThirdPartyUtility的初始化。并在两个函数上面添加@Provides注解。这样就可以实现不受我们控制的第三方类的初始化。

最后利用@Component注解添加一个用于连接ModuleClass和MainActivity类的桥梁接口,如下:

@Component(modules = {ModuleClass.class})
public interface ComponentClass {
    void inject(MainActivity mainActivity); 
}

通过@Component注解指定这是个Component类,并通过modules指定包含的Module类。添加一个inject函数,函数的参数就是要注入的目的类,在这里是MainActivity。
最后就是真正注入依赖的地方,在MainActivity中:

public class MainActivity extends AppCompatActivity {    
    ...
    @Inject    
    RecyclerViewAdapter viewAdapter;  
  
    @Override    
    protected void onCreate(Bundle savedInstanceState) {     
        ...   
        DaggerComponentClass.builder().moduleClass(new ModuleClass(this)).build().inject(this);        
        mRecyclerView.setAdapter(viewAdapter);      
        ...  
    }
    ...
}

这里Dagger框架根据Component类自动生成的一个辅助类DaggerComponentClass,通过这个类进行依赖注入,需要make一下工程生成这个辅助类。这样就完成了依赖viewAdapter的注入。运行代码,得到跟传统的new方式初始化依赖同样的效果。

更多的功能可以通过其他注解实现,如通过@Singleton实现单例,通过@Scope等注解实现作用域的指定等,这里不再介绍,可以参考Google文档进行了解和实践。

本文Github源码下载

参考:
https://github.com/google/dagger

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值