iT邦幫忙

2021 iThome 鐵人賽

DAY 24
0
Mobile Development

android studio 30天學習筆記系列 第 24

30天學習筆記 -day 24-Dagger (下篇)

  • 分享至 

  • xImage
  •  

今天會補充dagger的用法。
今天目標:一個 Acomponent 裡放著 Fruit.class 的依賴實例,另一個Bcomponent裡放著 Fruitshop.class 的依賴實例,Acomponent 公開Fruit的依賴實例讓 Bcomponent 也能獲取。

建立Fruit.Class

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;
    }
}

建立Fruitshop.class

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

Scope跟@Singleton一樣都是單例模式,被@Scope註解所標識的Component的生命週期內,只要是@Scope所標識提供依賴的方法,那麼所提供的依賴都是單例!

這次自訂義兩種scope:FruitScope跟FruitShopScope,除了命名不同其他都一樣

@Documented
@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface FruitScope {
}

Fruit2Module

將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;
    }
}

Fruit2Component

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

FruitShop1Module

將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;
    }
}

FruitShop1Component

moduleprovide方法有@FruitShopScope則使用該ModuleComponent也需要@FruitShopScope
@Component註解中加入使用的modules跟依賴的Component,就可以拿到Fruit2Component提供的功能。

@FruitShopScope
@Component(modules = FruitShop1Module.class,dependencies = Fruit2Component.class)
public interface FruitShop1Component {
    void inject(Test2Activity activity);
}

TestApplication.class

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會報錯

Test2Activity

@InjectFruitShop會自動賦值。

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回傳:
https://ithelp.ithome.com.tw/upload/images/20210911/201389660I1CpOFSfO.png

注意事項:
1.被依賴的component必須將需要的依賴實例暴露出來,其他有依賴關係的component才能被提供。
2.依賴關係中的component不能擁有相同的SCOPE,會因為生命週期不同而報錯。

以上就是今天的內容。


上一篇
30天學習筆記-day 23- Dagger (上篇)
下一篇
30天學習筆記 介紹-day 25-View Animation
系列文
android studio 30天學習筆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言