dagger2從入門到放棄-最基礎的用法介紹
前言
dagger2確實學習曲線比較陡峭,但是忘掉生命週期,忘掉區域性單例,忘掉SubComponent這樣的進階用法,只用最基礎最簡單的部分一樣可以給專案帶來一定程度的便利
依賴的提供方式
- @Inject註解構造器
- @Provides註解提供依賴的方法
@Inject註解構造器-用來提供依賴
- 表示該類可以作為依賴注入到依賴需求方
- 如果構造器帶引數,則這些引數也需要是可以提供的依賴,dagger2會自動找到這些依賴並注入
- 對於有多個構造器的類,@Inject只能註解其中一個
public class SimpleInjectExtraBean { @Inject public SimpleInjectExtraBean() { } }
@Inject建構函式帶引數的情況
建構函式中的引數需要是@Inject註解構造器的物件或者是@Provides方法提供的依賴
public class SimpleInjectBean extends BaseBean { public SimpleModuleBean mSimpleModuleBean; public SimpleInjectExtraBean mSimpleInjectExtraBean; @Inject public SimpleInjectBean(SimpleModuleBean simpleModuleBean, SimpleInjectExtraBean simpleInjectExtraBean) { mSimpleModuleBean = simpleModuleBean; mSimpleInjectExtraBean = simpleInjectExtraBean; } }
@Module @Provides 提供無法修改構造器的依賴
使用@Inject註解構造器是最簡單的提供依賴的方式,但是如果是一個第三方庫中的程式碼無法修改建構函式添加註解呢,這時候就需要module出場了
@Module //@Module註解可以提供依賴的類 public class SimpleModule { @Provides // @Provides 註解提供依賴的方法 public SimpleModuleBean provideSimpleModuleBean() { return new SimpleModuleBean(); } }
@Provides註解的方法帶引數
和@Inject註解的建構函式帶的引數一樣,也需要是@Inject註解構造器的物件或者是@Provides方法提供的依賴
依賴的接收方式
@Inject註解例項變數-用來接受依賴
public class SimpleActivity extends AppCompatActivity { @Inject SimpleInjectBean mSimpleInjectBean; ... }
連線依賴提供方和依賴接收方的Component
component是依賴提供方和依賴需求方的連線者,使用@Component註解,注意dagger2只能註解介面和抽象類,具體類註解了也生成不了注入相關的程式碼
對於@Inject不需要在Component中顯示指定
對於module,需要在用@Component的modules屬性顯示指定
@Component(modules = SimpleModule.class) public interface SimpleComponent { void inject(SimpleActivity simpleActivity); }
框架會生成DaggerXXXComponent的類,使用DaggerXXXComponent完成注入
public class SimpleActivity extends AppCompatActivity { @Inject SimpleInjectBean mSimpleInjectBean; @Inject SimpleInjectExtraBean mSimpleInjectExtraBean; @Inject SimpleModuleBean mSimpleModuleBean; ... private SimpleComponent mSimpleComponent; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); mSimpleComponent = DaggerSimpleComponent.create(); mSimpleComponent.inject(this); ... } }
以上就用dagger2實現了最簡單的依賴注入
不過這基本上接近於寫了一個HelloWorld
下面看一下更接近真實的簡單場景
提供一個執行時的依賴
dagger2實現依賴注入的實質是建立編譯期可以確定的所有類的工廠,在執行時通過dagger2生成的工廠程式碼(依賴注入框架內部)完成依賴的建立與管理
但是像Application,Activity這樣的物件的建立過程是android框架完成的,dagger2無法接管這個過程,而非常多的物件的建立會依賴於context,activity這樣的物件
為了解決這樣的問題,需要將這些執行時物件作為引數提供給dagger框架
為dagger框架提供引數有兩種方式
構造器帶引數的Module
以Application為例
@Module public class BaseAppModule { private Application mApplication; public BaseAppModule(Application application) { mApplication = application; } @Provides @Singleton Application provideApplication() { return mApplication; } @Provides @Singleton Context provideContext() { return mApplication; } }
Component的獲取方式也會變化
//before Component依賴的所有module的建構函式都沒帶引數,則可以直接通過DaggerXXXComponent.create()直接獲取對應的Component例項 DaggerBaseAppComponent.create(); //等價於DaggerXXXComponent.builder().build(); DaggerBaseAppComponent.builder().build(); //after 如果module中帶了引數,則編譯期不會生成create()方法 //需要使用.builder()傳入對應的Module作為引數,這時可以將Application例項作為Module的構造引數傳入 DaggerBaseAppComponent.builder().baseAppModule(new BaseAppModule(this)).build();
直接通過@Component.Builder傳入引數
@Component.Builder註解一個用來向Component繫結引數的介面
這裡以Activity為例,在Component.Builder中使用@BindsInstance註解一個傳入Activity的方法
//provideSimpleModuleActivityBean有一個Activity作為引數 @Module public class SimpleModule { @Provides public SimpleModuleActivityBean provideSimpleModuleActivityBean(Activity activity) { return new SimpleModuleActivityBean(activity); } } @Component(modules = SimpleModule.class) public interface SimpleComponent { void inject(SimpleActivity simpleActivity); @Component.Builder interface Builder { //建立Component的時候繫結例項 @BindsInstance Builder simpleActivity(Activity simpleActivity); SimpleComponent build(); } }
注意:如果SimpleModule建構函式還帶了引數,因為此時的Component.Builder是按照我們定義的而不是完全自動生成的,所以為能夠傳入Module中需要的引數,需要顯式指定該module作為builder的引數
@Component(modules = SimpleModule.class) @SimpleScope public interface SimpleComponent { void inject(SimpleActivity simpleActivity); @Component.Builder interface Builder { //建立Component的時候繫結例項 @BindsInstance Builder simpleActivity(Activity simpleActivity); //使用了Builder就需要顯式的指定帶引數的module作為builder的引數 Builder simpleModule(SimpleModule simpleModule); SimpleComponent build(); } }
總結
這篇文章介紹了為dagger提供依賴和注入依賴以及提供執行時引數的方法,不過離真實場景還是有一定的區別那就是生命週期的管理
下一篇文章將介紹dagger2中依賴的生命週期管理