iT邦幫忙

2022 iThome 鐵人賽

DAY 27
0

今天要來講一個android實現DI的一個套件--Dagger,由於Dagger用法及內容都相當豐富,今天我就著重我認為最基本的幾個重點來解釋,首先Dagger是透過annotation進行職責分配,接下來我將透過程式碼解釋幾個annotation。

gradle

implementation ‘com.google.dagger:dagger:2.17’

@Module

包含@Provide,標示負責提供物件的class。

@Module
public class MyModule {
     ...
}

@Provide

標示於Module內的Function旁,負責提供物件。命名通常是provide開頭且內容常為new一物件,或是獲取new好的物件。

@Module
public class MyModule {
    //獲取new 好的 MyPresenter,代表MyPresenter有Function@Provide或MyPresenter的建構元有下@Inject
    @Provides
    static MyController.Presenter providePresenter(MyPresenter presenter){
        return presenter;
    }
    //new 物件回傳
    @Provides
    static HttpLoggingInterceptor provideHttpLoggingInterceptor(){
        return new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY);
    }
    ...
}

@Named

用來標示並命名提供或者使用的變數,常用在@Provides的Function回傳值相同時,須標示命名,否則Dagger不知道要提供的內容為何。

@Module
public class MyModule {
    ...
    
    @Provides
    static MyServiceApi provideApiService(@Named("Retrofit") Retrofit retrofit){
        return retrofit.create(MyServiceApi.class);
    }
    
    @Named("Retrofit")
    @Provides
    static Retrofit provideRetrofit(@Named("testUrl_1") String baseUrl) {
        return new Retrofit.Builder()
                .baseUrl(baseUrl)
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .build();

    }
    @Named("testUrl_1")
    @Provides
    static String getBaseUrl_1(){
        return "https://jsonplaceholder.typicode.com/";
    }

    @Named("testUrl_2")
    @Provides
    static String getBaseUrl_2(){
        return "https://reqres.in/api/";
    }

@Component

包含Module、或其他Component(透過dependencies得以依賴)

@Component( dependencies = MainComponent.class,
            modules = MyModule.class)
public interface MyComponent {
    //將注入至MainActivity
    void inject(MainActivity activity);;
}

@Inject

  1. 物件旁加@Inject

    會從引用的component中的module 有 @Provide 標籤獲得。

public class MainActivity extends AppCompatActivity implements MyController.View {

    ...
    //會從引用的component中的module 有 @Provide 標籤獲得。
    @Inject
    MyServiceApi myServiceApi;
    
    ...
}
  1. 建構元加@Inject
    • 若建構元內沒有引數,則會幫你 new 一相對應物件。
    • 若建構元內有引數,則會找此物件在哪提供(@Inject、@Provide找)。
@Inject
public MyPresenter(MyServiceApi myServiceApi,MyController.View myView) {
    this.myServiceApi = myServiceApi;
    this.myView = myView;
}

記得以上如果設定好就需要進行Build,否則不會生成Dagger的class,這樣也就無法建立及使用dagger。

Activity內使用

  1. 宣告Component
//@Component標籤下的Class
private MyComponent myComponent;
  1. 建立Component
myComponent = DaggerMyComponent.builder().build();
  1. 呼叫@Component內的inject方法
myComponent.inject(this);

這樣就完成注入了,在Activity內的@Inject將可以透過剛剛建立的myComponent中的module裡的@Provide方法 或者其他@Inject標籤找到需要的物件。

老實講我認為Dagger入門門檻偏高,因為我也是看了無數篇文章才能使用這項工具,不過儘管如此我還是想介紹一下,這可以幫忙釐清許多觀念,了解到分工的重要性,在往後也能寫出更漂亮的code。


上一篇
精華筆記 Day26 - Dependency Injection(DI)
下一篇
精華筆記 Day28 - DataBinding
系列文
android studio 30天 精華筆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言