zoukankan      html  css  js  c++  java
  • Android 依赖注入: Dagger 2 实例解说(一)

    本文原创,转载请注明出处:http://blog.csdn.net/zjbpku

    [Duplicated]   link to  Dagger on Android - Dagger2具体解释

    关于Dagger,在之前的博文(Android 依赖注入:Dagger 实例解说(Demo下载))中已有介绍, 本文说的Dagger 2主要是由Google技术

    人员參与开发的。当然包含Square的各位及其它一些Contributors在内的大牛也贡献了不少。

    该项目大概是从去年11月份開始启动的。到眼下该项

    目还在继续进行,Snapshot version也是刚刚公布不久,从Github提供的内容看,不久会是Pre Release Version,然后才是Release Version,因为

    如今还是预览版,还不稳定,请慎重使用。到Pre Release时才会相对照较稳定。能够使用来进行项目开发。本人关注这个项目依然,就提前通过一

    个Demo来简介一下Dagger 2.

                                                                                     

    Dagger 2是Dagger 1.x的增强版。在Dagger 1.x中,@Inject和@Provides annotation 构成了对象的图谱(graph),依靠之间的依赖

    关系而链接在一起。

    通过定义好的图谱集(ObjectGraph)能够方便的调用代码。

    而在Dagger 2中。这样的关系被带有无參方法的接口取代,

    这样的方法返回的类型就是所需类型。

    这样的接口的实现是通过@Component 注解且传入modules參数来定义的。如:

    @Component(
    //        dependencies = ApplicationComponent.class,
            modules = ActivityModule.class
    )
    public interface ActivityComponent {
        MainActivity injectActivity(MainActivity activity);
    
        ToastHelper getToastHelper();
    }

    在编译时,Dagger 2会自己主动生成以Dagger_为前缀的此接口的实现Dagger_AcitvityComponent.通过调用此的builder()方法来获得一个

    实例,通过该方法返回的builder来设置其它依赖,通过build来获得一个新的实例。

     this.component = Dagger_ActivityComponent.builder()
    //                .applicationComponent(((DaggerApplication) getApplication()).getComponent())
                    .activityModule(new ActivityModule(this))
                    .build();

    另外一点,假设@Component注解的接口中的方法没有參数,生成的实例中会生成一个create()方法,此create()方法实际上就是
    builder().build();此点在以后的代码中会提到。

    以下介绍Demo:

    Demo使用最新的AndroidStudio (下面简称AS)1.0.2版本号,既然使用AS,就少不了gradle.build文件的配置。此项目gradle配置例如以下:

    apply plugin: 'com.android.application'
    apply plugin: 'android-apt'
    buildscript {
        repositories {
            jcenter()
        }
        dependencies {
            classpath 'com.android.tools.build:gradle:1.0.0'
            classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4' // 3
        }
    }
    
    allprojects {
        repositories {
            mavenCentral()
            maven {
                url 'https://oss.sonatype.org/content/repositories/snapshots/'
            }
        }
    }
    android {
        compileSdkVersion 21
        buildToolsVersion "21.1.2"
    
        defaultConfig {
            applicationId "com.example.zjbpku.dagger2"
            minSdkVersion 19
            targetSdkVersion 21
            versionCode 1
            versionName "1.0"
        }
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            }
        }
    }
    
    def Dagger2_Version = '2.0-SNAPSHOT'
    
    dependencies {
        compile fileTree(dir: 'libs', include: ['*.jar'])
        compile 'com.android.support:appcompat-v7:21.0.3'
        // 1. Dagger 2.0
        compile "com.google.dagger:dagger:$Dagger2_Version"
        apt "com.google.dagger:dagger-compiler:$Dagger2_Version"
        // 2.
        compile 'org.glassfish:javax.annotation:10.0-b28'
    }
    
    分别看一下gradle.build文件里凝视1。2,3。

    凝视1:是配置依赖Dagger 2,版本号是2.0-SNAPSHOT,这里相比之前版本号的Dagger就是从com.square.dagger 变为如今的com.google.dagger,

    当然这不是重点。

    凝视2:为什么要加上这一句呢?由于Dagger 2 中会用到@Generated注解(后面讲),而javax.anotation.generated在java 6及以上的版本号中都有,

    在Android API 中是没有的,所以在Android项目中一定要加此句,假设不加就有提示下面错误:

    error: cannot find symbol class Generated
    error: package javax.annotation does not exist

    凝视3:就不多少了,详细作用请看http://blog.csdn.net/zjbpku/article/details/22976291,另不要忘记加 

    apply plugin:android-apt

    在之前的Dagger中@module是一个关键注解,在Dagger 2中相同少不了,此Demo中用到的两个Module例如以下:(用过Dagger的不会认为有问题)

    ActivityModule.java:

    /**
     * Created by zjbpku on 12/20/14.
     */
    
    @Module
    public class ActivityModule {
    
        private Activity mActivity;
    
        public ActivityModule(Activity activity) {
            mActivity = activity;
        }
    
        @Provides
        Activity providesActivity() {
            return mActivity;
        }
    
    }

    ApplicationModule.java:

    /**
     * Created by zjbpku on 12/20/14.
     */
    @Module
    public class ApplicationModule {
        Application mApplication;
    
        ApplicationModule(Application application) {
            mApplication = application;
        }
    
        @Provides
        Application providesApplication() {
            return mApplication;
        }
    }

    写好之后,加入两个@Component注解的接口,此Demo很easy。仅仅是来尝试使用一下Dagger 2,Application相关的事实上能够不用,对Demo不会

    有什么影响,但在实际项目中还是必须加入的,所以这里也给加上。

    Activityomponent.java:

    /**
     * Created by zjbpku on 12/20/14.
     */
    
    @Component(
            dependencies = ApplicationComponent.class,
            modules = ActivityModule.class
    )
    public interface ActivityComponent {
        MainActivity injectActivity(MainActivity activity);
    
        ToastHelper getToastHelper(); 
    }


    ApplicationComponent.java:

    /**
     * Created by zjbpku on 12/20/14.
     */
    @Component(
            modules = ApplicationModule.class
    )
    public interface ApplicationComponent {
        DaggerApplication injectApplication(DaggerApplication application);
    }


    DaggerApplication.java:

    /**
     * Created by zjbpku on 12/20/14.
     */
    public class DaggerApplication extends Application {
    
        private ApplicationComponent component;
    
        @Override
        public void onCreate() {
            super.onCreate();
            this.component = Dagger_ApplicationComponent.builder().applicationModule(new ApplicationModule(this)).build();
            this.component.injectApplication(this);
        }
    
    
        ApplicationComponent getComponent() {
            return this.component;
        }
    }

    //加入仅仅是为了測试

    ToastHelper.java:

    /**
     * Created by zjbpku on 12/22/14.
     */
    public class ToastHelper {
    
        @Inject
        ToastHelper() {
        }
    
        //@Inject
        //Utils utils;
        Toast toast = null;
    
        public void showToast(Context context, CharSequence text) {
            if (toast == null) {
                toast = Toast.makeText(context, text, Toast.LENGTH_LONG);
            } else {
                toast.setText(text);
            }
            toast.show();
        }
    
        public void show(Context context) {
           // showToast(context, utils.getContent());
        }
    }


    MainActivity.java:

    package com.example.zjbpku.dagger2;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.view.View;
    
    
    public class MainActivity extends Activity {
    
        private ActivityComponent component;
    //    @Inject
    //    ToastHelper toastHelper;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            this.component = Dagger_ActivityComponent.builder()
                    .applicationComponent(((DaggerApplication) getApplication()).getComponent())
                    .activityModule(new ActivityModule(this))
                    .build();
            this.component.injectActivity(this);
            setContentView(R.layout.activity_main);
        }
    
    
        public void helloDagger2(View v) {
    //        toastHelper.showToast(this, "Dagger 2");
    //        toastHelper.show(this);
            this.component.getToastHelper().showToast(this, "Dagger 2 Demo");
        }
    
    }

            能够看到。Dagger 2 消除了Dagger 1.x 中全部的映射(reflection),通过加入@Component。移除ObjectGraph/Injector使代码更加的清晰了。

    到此,Dagger 2的基本使用方法已经结束,在ActivityComponet接口中你发现有getToastHelper()方法,在Mainctivity中发现@Inject注解的ToastHelper

    是注销的。且在helloDagger2(View v)方法中也是注销的。这是由于。開始时getToastHelper()方法是没有的。是直接在Mainctivity中通过@Inject直接注入

    的,后来阅读Dagger 2的相关资料发现,事实上这并非Dagger 2的所期望的,Dagger 2希望使用@Component注解接口将依赖关系链接起来,所以才改用

    如今这样的方法。事实上两种都能达到一样的效果。仅仅是Dagger自己主动生成的代码有所差异,这个之后会进一步介绍。




  • 相关阅读:
    html 的一些基础操作
    java 通过反射调用属性,方法,构造器
    java 通过反射获取类属性结构,类方法,类父类及其泛型,类,接口和包
    java 反射,类的加载过程以及Classloader类加载器
    java 随机读写访问流及seek方法
    java 序列化机制
    java 标准输入输出流,打印流,数据流
    hp400 硒鼓加粉图解
    Delphi XE5 android 获取网络状态
    Delphi XE5 常见问题解答
  • 原文地址:https://www.cnblogs.com/llguanli/p/6769062.html
Copyright © 2011-2022 走看看