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?


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM