zoukankan      html  css  js  c++  java
  • Dragger 2遇到的坑 Dragger2详解 Dragger2学习最好的资料

    我是曹新雨,我为自己代言。现在的菜鸟,3年以后我就是大神。为自己加油。微信:aycaoxinyu

    Dragger2是什么,我就不再说了。资料一堆,而且里面的注解什么意思,我推荐两篇文章,这两篇都是我精挑细选,一般的文章我是不推荐的。

    http://android.jobbole.com/82694/

    http://android.jobbole.com/82704/

    http://android.jobbole.com/82705/
    有了基础的了解,来跟我helloworld吧。
    第一步:配置依赖:

    //如果你用了butterknife,那么这个com.neenbedankt.gradle.plugins就不用再次引入了
    buildscript {
        repositories {
            mavenCentral()
        }
        dependencies {
            classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
        }
    }
    apply plugin: 'com.neenbedankt.android-apt'
    
    dependencies {
    
        apt 'com.google.dagger:dagger-compiler:2.0'
        compile 'com.google.dagger:dagger:2.0' // dagger2
    //    compile 'com.google.dagger:dagger-compiler:2.0.2' // dagger2
        provided 'org.glassfish:javax.annotation:10.0-b28'
    }

    第二步:

    走到这步我就遇到了一个坑,DaggerApplicationComponent这个类一直报找不到。

    后来才知道,要rebuild一下,因为这个类是自动生成的。

    解决了这个,然后跟着别人写代码,才算是入了点门。直到了写一个类的依赖注入,需要写三个东西:
    loginComponent
    LoginModel
    额,是两个就行了。就像:
    AppComponent
    AppModule
    这两个全局的。
    然后怎么依赖给它的,我还没弄懂。遇到了三个错误:

    Error:(6, 43) 错误: 找不到符号
    符号:   类 DaggerAppComponent
    位置: 程序包 com.chinaCEB.cebActivity.components
    Error:(19, 10) 错误: com.chinaCEB.cebActivity.view.ILoginActivity cannot be provided without an @Provides-annotated method.
    com.chinaCEB.cebActivity.view.LoginActivity.loginPresenter
    [injected field of type: com.chinaCEB.cebActivity.presenter.LoginPresenter loginPresenter]
    com.chinaCEB.cebActivity.presenter.LoginPresenter.<init>(com.chinaCEB.cebActivity.view.ILoginActivity loginActivity)
    [parameter: com.chinaCEB.cebActivity.view.ILoginActivity loginActivity]

    每当我不懂dragger2的时候,就看一边资料。这样,真的很有帮助。
    http://www.jianshu.com/p/c2feb21064bb

    AppComponent: 生命周期跟Application一样的组件。可注入到自定义的Application类中,@Singletion代表各个注入对象为单例。

    //component都是接口,到时候,dragger2会生成你的实现类。
    //就像DaggerAppComponent  你写了AppComponent就会有DaggerAppComponent这个实现类
    
    @Singleton
    @Component(modules = AppModule.class)
    public interface AppComponent {
        Context context();  // 提供Applicaiton的Context
    
        ThreadExecutor threadExecutor();   // 线程池
    
        ApiService apiService();  // 所有Api请求的管理类
    
        SpfManager spfManager();  // SharedPreference管理类
    
        DBManager dbManager();  // 数据库管理类
    }

    AppModule: 这里提供了AppComponent里的需要注入的对象。

    //可以发现,AppModule和AppComponent 是对应的
    //ThreadExecutor threadExecutor();   // 线程池
    /*@Provides
        @Singleton
        ThreadExecutor provideThreadExecutor(JobExecutor jobExecutor) {
            return jobExecutor;
        }
    */
    @Module
    public class AppModule {
        private final MyApplication application;
    
        public AppModule(MyApplication application) {
            this.application = application;
        }
    
        @Provides
        @Singleton
        Context provideApplicationContext() { 
           return application;
        }
    
        @Provides
        @Singleton
        ThreadExecutor provideThreadExecutor(JobExecutor jobExecutor) {
            return jobExecutor;
        }
    
        @Provides
        @Singleton
        ApiService providesApiService(RetrofitManager retrofitManager) {
            return retrofitManager.getService();
        }
    
        @Provides
        @Singleton
        SpfManager provideSpfManager() {
            return new SpfManager(application);
        }
    
        @Provides
        @Singleton
        DBManager provideDBManager() {
            return new DBManager(application);
        }
    }

    也就是AppComponent里面全都是对象,AppModule是它的实现。可是这些入参都是谁给的?

    终于知道activity是怎么得到的了。

    @Module
    public class ActivityModule {
        private final Activity activity;
    
        public ActivityModule(Activity activity) {
            this.activity = activity;
        }
    
        @Provides
        @ActivityScope
        Activity activity() {
            return this.activity;
        }
    }
    
    
    然后:
     //  建议写在基类Activity里
        protect ActivityModule getActivityModule(){
              return new ActivityModule(this);
        }

    搞了一天,终于搞定了。dragger2. 我知道我可以的。哼哼。
    我现在知道完整的dragger2步骤了。

    引入依赖之后:
    第二步:
    写AppComponent

    package com.chinaCEB.cebActivity.components;
    
    import android.content.Context;
    
    import com.chinaCEB.cebActivity.App;
    import com.chinaCEB.cebActivity.modules.AppModule;
    
    import javax.inject.Singleton;
    
    import dagger.Component;
    
    /**
     * Created by niuxiaowei on 16/3/19.
     */
    //AppModule: 这里提供了AppComponent里的需要注入的对象。
    @Singleton
    @Component(modules={AppModule.class})
    //AppComponent: 生命周期跟Application一样的组件。可注入到自定义的Application类中,@Singletion代表各个注入对象为单例。
    public interface AppComponent {
    
        Context getContext();
        void inject(App app);
    
    //    void inject(BaseActivity baseActivity);
    
    
    //    Test test();
    
    }
    

    只要你按照上面这种方法写的,那么,你的AppComponent 就会被dragger2换一个名字:DaggerAppComponent 。所有的都是。这就是rebuilt的结果。

    第三步:
    写完了AppComponent,写完了桥,那就该写model了

    import android.content.Context;
    
    import javax.inject.Singleton;
    
    import dagger.Module;
    import dagger.Provides;
    
    /**
     * Created by niuxiaowei on 16/3/19.
     */
    @Module
    public class AppModule {
    
    
        Context context;
    
        public AppModule(Context context){
            this.context = context;
        }
    
        @Provides @Singleton
        public Context provideContext(){
            return context;
        }
    
    
    
    
    //    @Provides @Singleton
    //    public Test provideTest(){
    //        return new Test();
    //    }
    }

    然后重复activity 的component ,module

    package com.chinaCEB.cebActivity.components;
    
    import com.chinaCEB.cebActivity.modules.ActivityModule;
    import com.chinaCEB.cebActivity.scope.PerActivity;
    import com.chinaCEB.cebActivity.view.LoginActivity;
    
    import dagger.Component;
    
    /**
     *
     * Created by niuxiaowei on 16/3/20.
     */
    //ActivityComponent,可以看到有个@ActivityScope注解,这个注解是自定义的,对应Activity的生命周期,Dagger2可以通过自定义注解限定注解作用域。
    //ActivityComponent:生命周期跟Activity一样的组件,这里提供了inject方法将Activity注入到ActivityComponent中,通过该方法,将Activity中需要注入的对象注入到该Activity中。
    @PerActivity
    @Component(dependencies = AppComponent.class,modules = {ActivityModule.class})
    public interface ActivityComponent {
        void inject(LoginActivity loginActivity);
    //    Activity getActivity();
    //    void inject(LoginActivity loginActivity);
    
    }
    

    void inject(LoginActivity loginActivity); 必须要写这个去掉不行

    activitymodel

    package com.chinaCEB.cebActivity.modules;
    
    import android.app.Activity;
    
    import com.chinaCEB.cebActivity.scope.PerActivity;
    import com.chinaCEB.cebActivity.view.ILoginActivity;
    import com.chinaCEB.cebActivity.view.LoginActivity;
    
    import dagger.Module;
    import dagger.Provides;
    
    /**
     * 提供baseactivity的module
     * Created by niuxiaowei on 16/3/20.
     */
    //ActivityModule:注入Activity,同时规定Activity所对应的域是@PerActivity
    @Module
    public class ActivityModule {
    
        private final Activity activity;
        public ActivityModule(Activity activity){
            this.activity = activity;
        }
    
    //    @Provides @PerActivity
    //    public Activity provideActivity(){
    //        return activity;
    //    }
        @Provides
        @PerActivity
        ILoginActivity provideILoginActivity() {
            return (LoginActivity) this.activity;
        }
    }
    
    
    
    
    

    model提供你的对象,也就是你用到的对象,初始化你要的present的时候,或者全局用到的对象

    @Provides
        @PerActivity
        ILoginActivity provideILoginActivity() {
            return (LoginActivity) this.activity;
        }

    然后在mvp 的p里面:

    public class LoginPresenter {
        private IUserbiz userbiz;
        private ILoginActivity loginActivity;
        private int i = -1;
    
        @Inject
        public LoginPresenter(ILoginActivity loginActivity) {
            this.loginActivity = loginActivity;
            userbiz=new Userbiz();
        }
    inject一下
    

    不得不说,dragger2很吊。全局 和局部的对象做的很好。

    之后再loginactivity:

    @Inject
        LoginPresenter loginPresenter;
    
    
    
    
    
    
    
    
    
    
    
    initInject();
     private void initInject() {
            // 构建Component并注入
            getActivityComponent().inject(this);
    //        loginPresenter.attachView(this);
        }
        // 建议写在MyApplication类里
        public AppComponent getAppComponent(){
            return DaggerAppComponent.builder()
                    .appModule(new AppModule((App)getApplicationContext()))
                    .build();
        }
    
        //  建议写在基类Activity里
        protected ActivityComponent getActivityComponent(){
            return  DaggerActivityComponent.builder()
                    .appComponent(getAppComponent())
                    .activityModule(getActivityModule())
                    .build();
        }
        //  建议写在基类Activity里
        protected ActivityModule getActivityModule(){
            return new ActivityModule(this);
        }
    

    ok,弄了一天,终于可以运行了。

    第一,我不知道DraggerAppComment是动态生成的。很坑。
    第二,就是原理理解的不到位,导致不知道怎么写。

    总结一个:
    dragger2 的作用就是依赖注入,并且分model和commpant, 比如okhttp全局一个就行,还有的是页面自己的一些对象,那么就写在自己的modules里面。

    说白了就是写两个文件,一个module,一个commpant,而且格式不就是那样的。

    哼,我为什么自卑。没有我做不到的。别人可以我也可以。不就是dragger2?

  • 相关阅读:
    蚂蚁问题
    LinuxC安装gcc
    怎样在VC里面使用graphics.h绘图
    C语言之固定格式输出当前时间
    C语言之猜数字游戏
    C语言之新同学年龄
    C语言之ASCII码
    C语言之辗转相除法
    C语言之自守数
    C语言之一数三平方
  • 原文地址:https://www.cnblogs.com/caoxinyu/p/10568746.html
Copyright © 2011-2022 走看看