接著上一篇Dagger2 使用總結(jié)(一)繼續(xù)總結(jié)Dagger2的使用方法芋簿。
Component接口的復(fù)用
我們可以適當(dāng)?shù)貜?fù)用Component接口灰署,從而使邏輯更加簡潔且減少不必要的重復(fù)工作润樱,復(fù)用一般使用dependencies
或者@Subcomponent
瑰剃,這兩者比較相似歪沃,要注意區(qū)分臣淤,先看實(shí)現(xiàn)再總結(jié)吧:
依賴 dependencies
場景:現(xiàn)在有Vegetable
抽象類和其兩個(gè)子類Tomato
和Potato
橄霉,項(xiàng)目中可能較多地方都需要注入這兩個(gè)類的對象。
這時(shí)候我們可以建立BaseComponent
接口邑蒋,其他需要使用這兩個(gè)對象的Component接口依賴于這個(gè)BaseComponent
接口即可注入這兩個(gè)對象姓蜂,如下:
- 新建
Vegetable
、Tomato
医吊、Potato
和VegetableModule
public abstract class Vegetable {
public abstract void print();
}
public class Tomato extends Vegetable{
@Override
public void print() {
Log.d(TAG, "This is a tomato");
}
}
public class Potato extends Vegetable {
@Override
public void print() {
Log.d(TAG,"This is a potato");
}
}
@Module
public class VegetableModule {
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
public @interface ProvideTomato{}
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
public @interface ProvidePotato{}
@Provides
@ProvideTomato
Vegetable provideTomato() {
return new Tomato();
}
@Provides
@ProvidePotato
Vegetable providePotato() {
return new Potato();
}
}
?
這些實(shí)現(xiàn)和注解在上一篇文章中都有說明钱慢,如果不了解可以回去翻一下。
- 新建
BaseComponent
接口
@Component (modules = VegetableModule.class)
public interface BaseComponent {
@VegetableModule.ProvideTomato Vegetable getTomato();
@VegetableModule.ProvidePotato Vegetable getPotato();
}
在這里使用getXXX
方法可以暴露這個(gè)接口可以獲得的對象卿堂,以使依賴其的接口可以獲得該對象束莫,如果不需要暴露則可不要編寫getXXX
方法以保持邏輯嚴(yán)謹(jǐn)。比如如果不需要暴露Potato
對象草描,可以將getPotato()
方法刪除览绿,這樣即便依賴了BaseComponent
接口,也無法獲得Potato
對象穗慕。
現(xiàn)在可以編譯項(xiàng)目以使build目錄下生成相關(guān)文件饿敲。
- 在
MainActivity
中實(shí)現(xiàn)依賴和注入
@Inject //屬性注入對象
@VegetableModule.ProvideTomato
public Vegetable tomato;
@Inject //屬性注入對象
@VegetableModule.ProvidePotato
public Vegetable potato;
@Component (dependencies = BaseComponent.class) //這里使用了dependencies依賴了BaseComponent接口
interface MainActivityComponent {
void inject(MainActivity activity);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DaggerMainActivity_MainActivityComponent
.builder()
.baseComponent(DaggerBaseComponent.builder().build()) //依賴的接口要在這里配置下
.build()
.inject(this);
tomato.print();
potato.print();
}
這樣就省去了直接編寫Component接口的實(shí)現(xiàn),直接使用dependencies
依賴即可逛绵。這種依賴方式的特點(diǎn)是可以實(shí)現(xiàn)暴露出的接口怀各,同時(shí)自身也可以擴(kuò)展自己的實(shí)現(xiàn)栗竖。
- 拓展
依賴關(guān)系也可以實(shí)現(xiàn)多依賴,容易理解就不解釋了渠啤,看代碼:
@Component (dependencies = {BaseComponent.class, OtherComponent.class}) //多依賴
interface MainActivityComponent {
void inject(MainActivity activity);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DaggerMainActivity_MainActivityComponent
.builder()
.baseComponent(DaggerBaseComponent.builder().build())
.otherComponent(DaggerOtherComponent.builder().build()) //這里注意也要配置下
.build()
.inject(this);
tomato.print();
potato.print();
}
?
@Subcomponent
和dependencies
區(qū)別在于狐肢,不需要父Component暴露出接口,也可以直接注入父Component中可注入的對象沥曹,有點(diǎn)像繼承關(guān)系份名。
為方便對比,還是剛剛的例子妓美,看看代碼實(shí)現(xiàn):
- 新建
Vegetable
僵腺、Tomato
、Potato
和VegetableModule
同上例壶栋。
- 新建
BaseComponent
@Component (modules = VegetableModule.class)
public interface BaseComponents {
MainActivityComponent plus(); //這里加一個(gè)返回SubComponent的方法
}
- 實(shí)現(xiàn)SubComponent
@Subcomponent (modules = FruitModule.class) //這里的@Subcomponent表示這是一個(gè)SubComponent接口
public interface MainActivityComponent {
void inject(MainActivity activity);
}
- 在
MainActivity
注入對象
DaggerDagger2Components_BaseComponents
.builder()
.build()
.plus() //這里返回MainActivityComponent
.inject(this);
這里只列出改變的地方辰如,其他代碼同上例。
總結(jié)
dependencies
和@SubComponent
都是實(shí)現(xiàn)了Component接口的復(fù)用贵试,使用dependencies
需要在父Component中暴露出需要注入的類(比如getXXX
)琉兜,而使用@SubComponent
不需要暴露類,而需要直接提供一個(gè)獲取SubComponent的方法毙玻。
為避免混亂豌蟋,建議一個(gè)模塊僅使用一種復(fù)用方式:
-
dependencies
適用于部分父Component中對象需要對子Component隱藏,或者公共注入類不多的情況桑滩。 -
@SubComponent
適用于父Component中公共注入類較多且不用隱藏的場景梧疲。
@Scope和@Singleton注解
我們可以用@Scope
管理注入類的作用域,@Singleton
是@Scope
的默認(rèn)實(shí)現(xiàn)方式运准。
待補(bǔ)充幌氮。