今天會補充dagger的用法。
今天目標:一個 Acomponent 裡放著 Fruit.class 的依賴實例,另一個Bcomponent裡放著 Fruitshop.class 的依賴實例,Acomponent 公開Fruit的依賴實例讓 Bcomponent 也能獲取。
public class Fruit {
private String name;
private String price;
public Fruit(String name,String price){
this.name=name;
this.price=price;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
}
Constructor放入兩個string類型(水果店名稱、電話)、一個Fruit類型(水果)
public class FruitShop {
private String fruitShopName;
private String shopPhone;
private Fruit fruit;
public FruitShop(String fruitShopName, String shopPhone,Fruit fruit){
this.fruitShopName=fruitShopName;
this.shopPhone=shopPhone;
this.fruit=fruit;
}
//getter&&setter
public String getFruitShopName() {
return fruitShopName;
}
public void setFruitShopName(String fruitShopName) {
this.fruitShopName = fruitShopName;
}
public String getShopPhone() {
return shopPhone;
}
public void setShopPhone(String shopPhone) {
this.shopPhone = shopPhone;
}
public Fruit getFruit() {
return fruit;
}
public void setFruit(Fruit fruit) {
this.fruit = fruit;
}
}
Scope跟@Singleton一樣都是單例模式,被@Scope註解所標識的Component的生命週期內,只要是@Scope所標識提供依賴的方法,那麼所提供的依賴都是單例!
這次自訂義兩種scope:FruitScope跟FruitShopScope,除了命名不同其他都一樣
@Documented
@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface FruitScope {
}
將Component 提供在Module,
Fruit2Module的部分在提供Fruit的地方加上@FruitScope
@Module
public class Fruit2Module {
private String name;
private String price;
//constructer
public Fruit2Module(String name,String price){
this.name=name;
this.price=price;
}
@Provides
@FruitScope
Fruit provideFruit(@Named("name")String name, @Named("price")String price){
return new Fruit(name,price);
}
@Provides
@Named("name")
String provideFruit1Name(){
return name;
}
@Provides
@Named("price")
String provideFruit1Price(){
return price;
}
}
module裡provide方法有@FruitScope則使用該Module的Component也需要@FruitScope。
@FruitScope
@Component(modules = Fruit2Module.class)
public interface Fruit2Component {
void inject(TestApplication testApplication);
//提供給其他Component使用
Fruit getFruit();
}Fruit getFruit();
將Fruit提供給其他有依賴關係的Component
將Component 提供在Module,
在FruitShop1Module提供的provideFruitShop中加入@FruitShopScope
@Module
public class FruitShop1Module {
private String fruitShopName;
private String shopPhone;
//Constructor
public FruitShop1Module(String fruitShopName,String shopPhone){
this.fruitShopName=fruitShopName;
this.shopPhone=shopPhone;
}
@Provides
@FruitShopScope
FruitShop provideFruitShop(@Named("ShopName")String fruitShopName,@Named("shopPhone")String shopPhone, Fruit fruit){
return new FruitShop(fruitShopName,shopPhone,fruit);
}
@Provides
@Named("ShopName")
String provideFruitShopName(){
return fruitShopName;
}
@Provides
@Named("shopPhone")
String provideFruitShopPhone(){
return shopPhone;
}
}
module
裡provide
方法有@FruitShopScope
則使用該Module
的Component
也需要@FruitShopScope
。@Component
註解中加入使用的modules跟依賴的Component,就可以拿到Fruit2Component提供的功能。
@FruitShopScope
@Component(modules = FruitShop1Module.class,dependencies = Fruit2Component.class)
public interface FruitShop1Component {
void inject(Test2Activity activity);
}
build之後就可以使用DaggerFruit2Component
public class TestApplication extends android.app.Application {
private Fruit2Component fruit2Component;
@Override
public void onCreate() {
super.onCreate();
fruit2Component= DaggerFruit2Component.builder()
.fruit2Module(new Fruit2Module("柚子","30"))
.build();
fruit2Component.inject(this);
}
//將fruit2Component返回
public Fruit2Component getFruit2Component(){
return fruit2Component;
}
}
這裡要注意!!
要在manifest加上android:name=".加上自定的Application",不然dagger會報錯
@Inject
FruitShop會自動賦值。
public class Test2Activity extends AppCompatActivity {
private FruitShop1Component fruitShop1Component;
@Inject
FruitShop fruitShop;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test2);
fruitShop1Component=DaggerFruitShop1Component.builder()
.fruitShop1Module(new FruitShop1Module("123水果店","0x00000000"))
//拿到TestApplication中getFruit2Component()
.fruit2Component(((TestApplication)getApplication()).getFruit2Component())
.build();
fruitShop1Component.inject(this);
Log.d("fruit", fruitShop.getFruit().getName());
Log.d("fruitshop",fruitShop.getFruitShopName());
}
}
Log回傳:
注意事項:
1.被依賴的component必須將需要的依賴實例暴露出來,其他有依賴關係的component才能被提供。
2.依賴關係中的component不能擁有相同的SCOPE,會因為生命週期不同而報錯。
以上就是今天的內容。