Dagger2使用方法

欢迎Follow我的GitHub, 关注我的CSDN, 合作请联系我.

Dagger已经加入Google I/O, 是Square开发的依赖注入库, 发布2.0版本. Dagger表示有向非循环图(Directed Acyclic Graph, DAGger). 好处和优点有很多, 参考, 所有优秀的开源库, 本质上都是让程序更加清晰, 编写更加容易. 让我们来看看怎么使用?

主要内容:

(1) 项目的配置环境.

(2) Inject\Module\Component的使用方法.

(3) 结合Retrofit和RxAndroid.

1. 配置

从一个最简单的HelloWorld开始, 设置build.gradle, 并添加依赖库.

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath ‘com.neenbedankt.gradle.plugins:android-apt:1.8‘
    }
}

// Lambda表达式
plugins {
    id "me.tatarka.retrolambda" version "3.2.4"
}

apply plugin: ‘com.android.application‘
apply plugin: ‘com.neenbedankt.android-apt‘ // 注释处理

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.2"

    defaultConfig {
        applicationId "clwang.chunyu.me.wcl_dagger_demo"
        minSdkVersion 17
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile(‘proguard-android.txt‘), ‘proguard-rules.pro‘
        }
    }

    // 注释冲突
    packagingOptions {
        exclude ‘META-INF/services/javax.annotation.processing.Processor‘
    }

    // 使用Java1.8
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

dependencies {
    compile fileTree(dir: ‘libs‘, include: [‘*.jar‘])
    testCompile ‘junit:junit:4.12‘
    compile ‘com.android.support:appcompat-v7:23.1.1‘
    compile ‘com.android.support:recyclerview-v7:23.1.1‘ // RecyclerView

    compile ‘com.jakewharton:butterknife:7.0.1‘ // 标注

    compile ‘com.google.dagger:dagger:2.0.2‘ // dagger2
    compile ‘com.google.dagger:dagger-compiler:2.0.2‘ // dagger2

    compile ‘io.reactivex:rxandroid:1.1.0‘ // RxAndroid
    compile ‘io.reactivex:rxjava:1.1.0‘ // 推荐同时加载RxJava

    compile ‘com.squareup.retrofit:retrofit:2.0.0-beta2‘ // Retrofit网络处理
    compile ‘com.squareup.retrofit:adapter-rxjava:2.0.0-beta2‘ // Retrofit的rx解析库
    compile ‘com.squareup.retrofit:converter-gson:2.0.0-beta2‘ // Retrofit的gson库

    provided ‘javax.annotation:jsr250-api:1.0‘ // Java标注
}

Gradle的配置与功能.

android-apt, 提供dagger2使用编译生成类的功能.

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath ‘com.neenbedankt.gradle.plugins:android-apt:1.8‘
    }
}

apply plugin: ‘com.neenbedankt.android-apt‘ // 注释处理

retrolambda, 提供Lambda表达式支持的功能.

// Lambda表达式
plugins {
    id "me.tatarka.retrolambda" version "3.2.4"
}

android{
    ...
    // 使用Java1.8
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

recyclerview, 提供RecyclerView控件的功能.

   compile ‘com.android.support:recyclerview-v7:23.1.1‘ // RecyclerView

butterknife, 提供xml至java的id映射的功能.

   compile ‘com.jakewharton:butterknife:7.0.1‘ // 标注

dagger2, 提供dagger2支持的功能.

    compile ‘com.google.dagger:dagger:2.0.2‘ // dagger2
    compile ‘com.google.dagger:dagger-compiler:2.0.2‘ // dagger2

rx, 提供rxandroid和rxjava支持的功能.

    compile ‘io.reactivex:rxandroid:1.1.0‘ // RxAndroid
    compile ‘io.reactivex:rxjava:1.1.0‘ // 推荐同时加载RxJava

retrofit, 提供网络请求的支持的功能.

    compile ‘com.squareup.retrofit:retrofit:2.0.0-beta2‘ // Retrofit网络处理
    compile ‘com.squareup.retrofit:adapter-rxjava:2.0.0-beta2‘ // Retrofit的rx解析库
    compile ‘com.squareup.retrofit:converter-gson:2.0.0-beta2‘ // Retrofit的gson库

annotation, 提供java注释解析的功能.

    provided ‘javax.annotation:jsr250-api:1.0‘ // Java标注

2. 主活动

使用主页跳转页面展示dagger2.

dagger2主要包含inject, module, component三个部分, 即:

Inject, 依赖注入dependency injection, 把定义的类注入声明.

Module, 模块, 提供若干类, 在依赖注入中使用.

Component, 组件, 注册若干模块至项目中.

提供图接口, 在项目中, 使用注入的类.

/**
 * Dagger2的图接口
 * <p/>
 * Created by wangchenlong on 16/1/2.
 */
public interface DemoGraph {
    void inject(MainActivity mainActivity); // 注入MainActivity

    void inject(ReposListActivity reposListActivity); // 注入列表Activity
}

组件, 注册Module, 添加主Module.

/**
 * 组件
 * Created by wangchenlong on 16/1/2.
 */
@Singleton
@Component(modules = {MainModule.class, ApiModule.class})
public interface DemoComponent extends DemoGraph {
    final class Initializer {
        private Initializer() {
        } // No instances.

        // 初始化组件
        public static DemoComponent init(DemoApplication app) {
            return DaggerDemoComponent.builder()
                    .mainModule(new MainModule(app))
                    .build();
        }
    }
}

如果没有Module可以暂时不添加, 但是要提供类, 项目注册需要使用中间类.

DaggerDemoComponent是自动生成的类, Dagger+类名.

项目的应用, 把Application添加至组件, 并提供注册类的图接口.

/**
 * 应用信息
 * <p/>
 * Created by wangchenlong on 16/1/2.
 */
public class DemoApplication extends Application {
    private static DemoGraph sDemoGraph;
    private static DemoApplication sInstance;

    @Override public void onCreate() {
        super.onCreate();
        sInstance = this;
        buildComponentAndInject();
    }

    public static DemoGraph component() {
        return sDemoGraph;
    }

    public static void buildComponentAndInject() {
        sDemoGraph = DemoComponent.Initializer.init(sInstance);
    }
}

主活动, 注册入图, 并添加跳转下一页功能.

/**
 * 主活动, 注册类.
 */
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ButterKnife.bind(this);

        DemoApplication.component().inject(this); // 应用注入
    }

    // 跳转列表视图
    public void gotoReposList(View view) {
        startActivity(new Intent(this, ReposListActivity.class));
    }
}

主模块, 提供Application和Resources.

/**
 * 主要模块, 提供Application和resources.
 * <p/>
 * Created by wangchenlong on 16/1/2.
 */
@Module
public class MainModule {
    private final DemoApplication mApp;

    public MainModule(DemoApplication application) {
        mApp = application;
    }

    @Provides
    @Singleton
    protected Application provideApplication() {
        return mApp;
    }

    @Provides
    @Singleton
    protected Resources provideResources() {
        return mApp.getResources();
    }
}

方法名添加@Provides@Singleton, 使用时, 添加@Inject即可. 表示在Module中创建, 在其他类中, 可以任意注入使用.

方法的参数, 因为没有调用方法的过程, 所以需要模块(Module)提供.

3. 其他活动

主要是列表展示GitHub用户的库信息, 使用Retrofit和RxAndroid的方法.

使用RecyclerView展示库信息, 注入类到图中, 并注入Github服务, Rx分发信息.

/**
 * 代码库列表
 * <p>
 * Created by wangchenlong on 16/1/2.
 */
public class ReposListActivity extends Activity {
    @Bind(R.id.repos_rv_list) RecyclerView mRvList;

    @Inject
    GitHubService mGitHubService;

    @Override protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_repos_list);
        ButterKnife.bind(this);

        DemoApplication.component().inject(this);

        LinearLayoutManager manager = new LinearLayoutManager(this);
        manager.setOrientation(LinearLayoutManager.VERTICAL);
        mRvList.setLayoutManager(manager);

        ListAdapter adapter = new ListAdapter();
        mRvList.setAdapter(adapter);
        loadData(adapter);
    }

    // 加载数据
    private void loadData(ListAdapter adapter) {
        mGitHubService.getRepoData("SpikeKing")
                .subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(adapter::setRepos);
    }
}

适配器.

/**
 * RecyclerView的Adapter
 * <p>
 * Created by wangchenlong on 16/1/2.
 */
public class ListAdapter extends RecyclerView.Adapter<ListAdapter.RepoViewHolder> {

    private ArrayList<Repo> mRepos; // 库信息

    public ListAdapter() {
        mRepos = new ArrayList<>();
    }

    public void setRepos(ArrayList<Repo> repos) {
        mRepos = repos;
        notifyItemInserted(mRepos.size() - 1);
    }

    @Override
    public RepoViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.item_repo, parent, false);
        return new RepoViewHolder(view);
    }

    @Override public void onBindViewHolder(RepoViewHolder holder, int position) {
        holder.bindTo(mRepos.get(position));
    }

    @Override public int getItemCount() {
        return mRepos.size();
    }

    public static class RepoViewHolder extends RecyclerView.ViewHolder {

        @Bind(R.id.item_iv_repo_name) TextView mIvRepoName;
        @Bind(R.id.item_iv_repo_detail) TextView mIvRepoDetail;

        public RepoViewHolder(View itemView) {
            super(itemView);
            ButterKnife.bind(this, itemView);
        }

        public void bindTo(Repo repo) {
            mIvRepoName.setText(repo.name);
            mIvRepoDetail.setText(String.valueOf(repo.description + "(" + repo.language + ")"));
        }
    }

    public static class Repo {
        public String name; // 库的名字
        public String description; // 描述
        public String language; // 语言
    }
}

GitHub请求接口, 返回Rx的观察者.

/**
 * GitHub服务
 * <p>
 * Created by wangchenlong on 16/1/2.
 */
public interface GitHubService {
    String ENDPOINT = "https://api.github.com";

    // 获取库, 获取的是数组
    @GET("/users/{user}/repos")
    Observable<ArrayList<ListAdapter.Repo>> getRepoData(@Path("user") String user);
}

Api模块, 使用请求接口创建GitHub服务.

/**
 * 接口模块
 * <p>
 * Created by wangchenlong on 16/1/2.
 */
@Module
public class ApiModule {

    @Provides
    @Singleton
    protected GitHubService provideGitHubService() {
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(GitHubService.ENDPOINT)
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) // 添加Rx适配器
                .addConverterFactory(GsonConverterFactory.create()) // 添加Gson转换器
                .build();
        return retrofit.create(GitHubService.class);
    }
}

不要忘记, 注册模块(Module)到组件(Component). 组件组成到应用, 模块注册到组件.

dagger2的重要优势就是省略了很多重复的创建, 直接依赖注入非常简单.

效果

GitHub下载地址

OK, that’s all! Enjoy It!

时间: 2024-12-25 15:01:00

Dagger2使用方法的相关文章

手把手带你走进MVP +Dagger2 + DataBinding+ Rxjava+Retrofit 的世界

0.0 Android开发现在的变化用一个词来形容就是 :翻天覆地 越来越多的项目使用了MVP + Rxjava+Retrofit +Dagger2 + DataBinding等等东西.. 但是这些东西对于木有用过的同学们开起来还是比较头疼的. 转载请标明出处:http://blog.csdn.net/wingichoy/article/details/51981756 网上有很多介绍他们的教程,但是都比较详细(我听到有童鞋问:详细还不好?? 其实他们最好的学习方式还是边敲边踩坑边学,一下介绍的

Dagger2系列之使用方法

本系列只讲使用方法和使用中遇到的问题,如果还对dagger2还不了解的童鞋儿可以参考文章: http://www.jianshu.com/p/cd2c1c9f68d4 http://www.jianshu.com/p/94d47da32656 使用Dagger2的前提需要添加一些依赖: 1 在Project的 build.gradle文件添加以下内容 buildscript { repositories { jcenter() } dependencies { classpath 'com.an

Android实现文章+评论(MVP,RxJava,Dagger2,ButterKnife)

简介 这个项目主要有两个功能,一个加载网页/文章,另一个用来显示评论.并应用了MVP模式,Dagger2.RxJava.ButterKnife等开源框架.效果图如下: 结构 首先来看一下布局文件: <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.andr

使用dagger2进行依赖注入(基础篇)

0. 前言 Dagger2是首个使用生成代码实现完整依赖注入的框架,极大减少了使用者的编码负担,本文主要介绍如何使用dagger2进行依赖注入.如果你不还不了解依赖注入,请看这一篇. 1. 简单的依赖注入 首先我们构建一个简单Android应用.我们创建一个UserModel,然后将它显示到TextView中.这里的问题是,在创建UserModel的时候,我们使用了前文所说的hard init.一旦我们的UserModel的创建方式发生了改变(比如需要传入Context对象到构造函数),我们就需

【Dagger2】简介 配置 使用 MVP案例

简介 dagger2:https://github.com/google/dagger Maven Central  2.11版本jar包下载 dagger:https://github.com/square/dagger compile 'com.google.dagger:dagger:2.11'//2017-9-17最新版本为[2.11] annotationProcessor 'com.google.dagger:dagger-compiler:2.11'//dagger-compile

Dagger2 使用初步

Dagger2 是一个Android依赖注入框架,由谷歌开发,最早的版本Dagger1 由Square公司开发.依赖注入框架主要用于模块间解耦,提高代码的健壮性和可维护性.Dagger 这个库的取名不仅仅来自它的本意“匕首”,同时也暗示了它的原理.Jake Wharton 在对 Dagger 的介绍中指出,Dagger 即 DAG-er,这里的 DAG 即数据结构中的 DAG——有向无环图(Directed Acyclic Graph).也就是说,Dagger 是一个基于有向无环图结构的依赖注入

【Android 进阶】Dagger2 系列:入门案例一

介绍 A fast dependency injector for Android and Java. 一个在 Android 和 Java 平台上使用的快速的依赖注入框架. 类似 java 开发中的 spring 框架,但使用难度比 spring 大一点点. 依赖注入框架主要用于模块间解耦,提高代码的健壮性和可维护性. 几个必须知道的概念: 什么是依赖: 如果在 Class A 中,有 Class B 的实例,则称 Class A 对 Class B 有一个依赖. 什么是依赖注入: 依赖注入就

可靠的功能测试 - Espresso和Dagger2

欢迎Follow我的GitHub, 关注我的CSDN. 可靠的功能测试, 意味着在任何时候, 获取的测试结果均相同, 这就需要模拟(Mock)数据. 测试框架可以使用Android推荐的Espresso. 模拟数据可以使用Dagger2, 一种依赖注入框架. Dagger2已经成为众多Android开发者的必备工具, 是一个快速的依赖注入框架,由Square开发,并针对Android做了特别优化, 已经被Google进行Fork开发. 不像其他的依赖注入器, Dagger2没有使用反射, 而是使

Dagger2 生成代码学习

接上一篇文章介绍了Dagger2的初步使用,相信刚接触的人会觉得很奇怪,怎么会有很多自己没有定义的代码出现,为什么Component的创建方式是那样的.为了搞清楚这些东西,我们需要查看一下Dagger2 生成的源代码.Dagger2 是一个DI框架,通过学习生成的代码也可以更好的理解Dagger2是如何做依赖注入的. 将上一篇文章中的工程在SublimeText中打开,结构如下图: 可以看到AppComponent 生成了 DaggerAppComponent,Dagger2的生成规则中,我们自