前言:html
當 mvp + dagger2 + rxjava 三者趕上,架構更加清晰,代碼更加靈活,巧妙結合。java
依賴注入:是爲了解耦,達到高內聚低耦合的目的,保證代碼的健壯性、靈活性和可維護性。android
1 public class Computer{ 2 3 private Cpu cpu; 4 5 public Computer(){ 6 cpu= new Cpu(); 7 } 8 }
Computer類持有了對Cpu實例的引用,稱之爲Computer類對Cpu類有一個依賴。api
依賴注入則是指經過注入的方式實現類與類之間的依賴。架構
一、構造注入:經過構造函數傳參,給依賴的成員變量賦值,所以實現注入。app
1 public class Computer{ 2 3 private Cpu cpu; 4 5 public Computer(Cpu cpu){ 6 this.cpu= cpu; 7 } 8 }
二、接口注入:實現事先定義好的接口方法,經過方法傳參的方式實現注入。ide
public interface Injection<T>{ void inject(T t); } public class Computer implements Injection<Cpu>{ private Cpu cpu; public Computer(){ } public void inject(Cpu cpu){ this.cpu= cpu; } }
三、註解注入:使用Java註解,在編譯階段生成代碼實現注入或者是在運行階段經過反射實現注入。函數
public class Computer{ @Inject private Cpu cpu; public Computer(){ } }
Dagger2是經過Java註解在編譯期來實現依賴注入的。學習
Dagger2的經常使用註解:gradle
@Inject:
一、用來標記須要依賴的變量,須爲它提供依賴;
二、是用來標記構造函數,Dagger2經過@Inject註解能夠在須要這個類實例的時候來找到這個構造函數並把相關實例構造出來,以此來爲被@Inject標記了的變量提供依賴;
@Module:
用於標註提供依賴的類。當構造函數帶有參數,或者是第三方庫類時,所須使用的。
@Provides:
用於標註Module所標註的類中的方法,該方法在須要提供依賴時被調用,把預先提供好的對象當作依賴給標註了@Inject的變量賦值;
@Component:
用於標註接口,是依賴需求方和依賴提供方之間的橋樑。被Component標註的接口在編譯時會生成該接口的實現類(若是@Component標註的接口爲CarComponent,則編譯期生成的實現類爲DaggerCarComponent),咱們經過調用這個實現類的方法完成注入;
@Scope:
用於自定義註解,我能能夠經過@Scope自定義的註解來限定註解做用域,實現局部的單例;
@Singleton:
其實就是一個經過@Scope定義的註解,咱們通常經過它來實現全局單例。但實際上它並不能提早全局單例,是否能提供全局單例還要取決於對應的Component是否爲一個全局對象。
案例一:
沒有使用注入時:
public class MainActivity extends ActionBarActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); User user = new User(); ((TextView) findViewById(R.id.tv_username)).setText("user name:" + user.name); } ... }
使用注入時:
設置 build.gradle
, 並添加依賴庫.
android-apt
, 提供 dagger2使用編譯生成類 的功能.
1 buildscript { 2 repositories { 3 jcenter() 4 } 5 dependencies { 6 classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8' 7 } 8 } 9 10 apply plugin: 'com.neenbedankt.android-apt' // 註釋處理
dagger2
, 提供 dagger2支持 的功能.
1 compile 'com.google.dagger:dagger:2.0.2' // dagger2 2 compile 'com.google.dagger:dagger-compiler:2.0.2' // dagger2
annotation
, 提供 java註釋解析 的功能.
1 provided 'javax.annotation:jsr250-api:1.0' // Java標註
配置完成後:
首先定義Module類來生成依賴對象。使用@Provides是用來標註具體提供依賴對象的方法。
1 @Module 2 public class DataModule { 3 4 @Provides 5 UserModel provideUser() { 6 return new User(); 7 } 8 }
定義component:注入器,加上modules = {DataModule.class},是用來告訴Dagger2提供依賴的是DataModule這個類:
1 @Component(modules = DataModule.class) 2 public interface ActivityComponent { 3 void inject(MainActivity activity); 4 }
最後使用方式:構建時,使用dataModule(new DataModule()),注入器DaggerActivityComponent把DataModule提供的依賴 注入到 MainActivity中,注入,使用
1 public class MainActivity extends ActionBarActivity { 2 3 private ActivityComponent mActivityComponent; 4 5 @Inject 6 User user; 7 8 @Override 9 protected void onCreate(Bundle savedInstanceState) { 10 super.onCreate(savedInstanceState); 11 setContentView(R.layout.activity_main); 12 13 // 構建 14 mActivityComponent = DaggerActivityComponent.builder().dataModule(new DataModule()).build(); 15 16 // 注入 17 mActivityComponent.inject(this); 18 19 ((TextView) findViewById(R.id.tv_username)).setText("user name:" + user.username); 20 } 21 ... 22 }
附言:
當復仇者聯盟趕上Dagger二、RxJava和Retrofit的巧妙結合