前面兩篇:
Dagger2 使用總結(jié)(一)
Dagger2 使用總結(jié)(二)
主要針對Dagger2的基礎(chǔ)庫進(jìn)行了簡單的總結(jié)疙教,這一篇會重點(diǎn)講述Dagger2的Android支持庫聋溜,它對Android組件進(jìn)行了定制推正,使代碼更加簡潔葛圃。
簡單用例
場景:向MainActivity
中注入MainPresenter
對象
- 導(dǎo)入相關(guān)庫
implementation "com.google.dagger:dagger:2.11"
implementation "com.google.dagger:dagger-android:2.11"
implementation "com.google.dagger:dagger-android-support:2.11"
annotationProcessor "com.google.dagger:dagger-compiler:2.11"
annotationProcessor "com.google.dagger:dagger-android-processor:2.11"
MainPresenter
類
public class MainPresenter {
@Inject //構(gòu)造器注入
public MainPresenter() {
}
public void print() {
Log.d(TAG, "This is a MainPresenter");
}
}
- 核心代碼
public class AppApplication extends DaggerApplication implements HasSupportFragmentInjector {
@Inject
DispatchingAndroidInjector<Fragment> fragmentSupportInjector;
@Override
protected AndroidInjector<? extends DaggerApplication> applicationInjector() {
return DaggerAppComponent.create();
}
@Override
public AndroidInjector<Fragment> supportFragmentInjector() {
return fragmentSupportInjector;
}
}
DaggerApplication來源于支持庫且有兩個(gè):
dagger.android.DaggerApplication
:支持普通組件淫僻,不支持?jǐn)U展(v4溪胶,v7)組件
dagger.android.supportDaggerApplication
:支持?jǐn)U展組件躯嫉,不支持普通組件
如果項(xiàng)目中需要支持兩種類型的組件纱烘,可以采用上述代碼中的形式,即:
繼承dagger.android.DaggerApplication
并實(shí)現(xiàn)HasSupportFragmentInjector
接口祈餐。
@Component (modules = {
ActivityModule.class, // 用于綁定項(xiàng)目中的Activity
AndroidSupportInjectionModule.class, // 用于綁定擴(kuò)展的組件擂啥,如v4
AndroidInjectionModule.class}) // 用于綁定普通的組件
public interface AppComponent extends AndroidInjector<AppApplication>{
}
// 注意這里用的是抽象類和抽象方法
@Module
public abstract class ActivityModule {
@ContributesAndroidInjector
abstract MainActivity mainActivity(); // 綁定MainActivity
}
這里寫ActivityModule
類只為了邏輯清晰,也可以將其內(nèi)部實(shí)現(xiàn)直接寫到AppComponent
中帆阳。
以上代碼是該例實(shí)現(xiàn)的重點(diǎn)哺壶,先不急去理解,因?yàn)槠涓袷悄0寤拇a蜒谤,先知其然山宾,再慢慢知其所以然。
現(xiàn)在我們已經(jīng)實(shí)現(xiàn)了將MainActivity
綁定到框架中鳍徽,下面看一下怎么注入對象资锰。
- 在
MainActivity
中注入MainPresenter
public class MainActivity extends DaggerAppCompatActivity { // 繼承定制的Dagger組件
@Inject //現(xiàn)在只要簡單的聲明即可注入
MainPresenter mainPresenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mainPresenter.print();
}
}
- 小結(jié)
可以這樣理解,我們先用應(yīng)用的AppApplication
和AppComponent
類搭好一個(gè)依賴注入的框架阶祭,而需要注入對象的組件绷杜,通過聲明和繼承綁定到框架中,即可注入對象濒募。相比于普通的Dagger2使用鞭盟,我們省略了以下步驟:
@Component
interface MainActivityComponent {
void inject(MainActivity activity);
}
...
DaggerMainActivity_MainActivityComponent.builder().build().inject(this);
?
@Binds
類似于@Provides
,在使用接口聲明時(shí)使用瑰剃,區(qū)別是@Binds
用于修飾抽象類中的抽象方法的齿诉,看下實(shí)例吧。
場景:將MainPresenter
注入到MainActivity
中
Presenter
接口和MainPresenter
public interface Presenter {
void print();
}
public class MainPresenter implements Presenter {
@Inject // 構(gòu)造器注入
public MainPresenter() {
}
@Override
public void print() {
Log.d(TAG, "This is MainPresenter");
}
}
- 添加一個(gè)
MainModule
類來統(tǒng)一管理
// 注意也要用抽象類和抽象方法
@Module
public abstract class MainMoudle {
// 這個(gè)方法必須返回接口或抽象類培他,比如Presenter鹃两,不能直接返回MainPresenter
// 方法的參數(shù)就是這個(gè)方法返回的是注入的對象遗座,類似@Provides修飾的方法返回的對象
// 這里的MainPresenter會通過上述聲明的構(gòu)造器注入自動(dòng)構(gòu)建
@Binds
abstract Presenter mainPresenter(MainPresenter mainPresenter);
}
@Component (modules = {
ActivityModule.class, // AppComponent這里要加上ActivityModule
AndroidSupportInjectionModule.class,
AndroidInjectionModule.class})
public interface AppComponent extends AndroidInjector<AppApplication>{
}
- 在
MainActivity
中自動(dòng)注入對象
public class MainActivity extends DaggerAppCompatActivity {
@Inject // 屬性注入即可舀凛,聲明的是接口
Presenter mainPresenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mainPresenter.print();
}
}
- 小結(jié)
將上述的
@Binds
abstract Presenter mainPresenter(MainPresenter mainPresenter);
換成
@Provides
static Presenter mainPresenter(MainPresenter mainPresenter) {
return new mainPresenter();
}
也是可以的,使用@Binds
相比@Provides
的好處是途蒋,更有效率猛遍。
- 擴(kuò)展
要給MainPresenter
加兩個(gè)int
參數(shù)id
,type
:
// 修改MainMoudle,使用@Provides提供注入懊烤,@Qualifier區(qū)分兩個(gè)參數(shù)
public abstract class MainMoudle {
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
public @interface MainPresenterId{}
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
public @interface MainPresenterType{}
@Provides
@MainPresenterId
static int getMainPresenterId() { // 注意是靜態(tài)方法
return 100; // 這里就簡單返回int值
}
@Provides
@MainPresenterType
static int getMainPresenterType() {
return 200;
}
@Binds
abstract Presenter mainPresenter(MainPresenter mainPresenter);
}
public class MainPresenter implements Presenter {
private int id;
private int type;
//參數(shù)對應(yīng)之前的@Qualifier聲明的注解
@Inject
public MainPresenter(@MainMoudle.MainPresenterId int id, @MainMoudle.MainPresenterType int type) {
this.id = id;
this.type = type;
}
@Override
public void print() {
Log.d(TAG, "This is MainPresenter id = " + id
+ " type = " + type);
}
}