今天要來講一個android實現DI的一個套件--Dagger,由於Dagger用法及內容都相當豐富,今天我就著重我認為最基本的幾個重點來解釋,首先Dagger是透過annotation進行職責分配,接下來我將透過程式碼解釋幾個annotation。
implementation ‘com.google.dagger:dagger:2.17’
包含@Provide,標示負責提供物件的class。
@Module
public class MyModule {
...
}
標示於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);
}
...
}
用來標示並命名提供或者使用的變數,常用在@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/";
}
包含Module、或其他Component(透過dependencies得以依賴)
@Component( dependencies = MainComponent.class,
modules = MyModule.class)
public interface MyComponent {
//將注入至MainActivity
void inject(MainActivity activity);;
}
會從引用的component中的module 有 @Provide 標籤獲得。
public class MainActivity extends AppCompatActivity implements MyController.View {
...
//會從引用的component中的module 有 @Provide 標籤獲得。
@Inject
MyServiceApi myServiceApi;
...
}
@Inject
public MyPresenter(MyServiceApi myServiceApi,MyController.View myView) {
this.myServiceApi = myServiceApi;
this.myView = myView;
}
記得以上如果設定好就需要進行Build,否則不會生成Dagger的class,這樣也就無法建立及使用dagger。
//@Component標籤下的Class
private MyComponent myComponent;
myComponent = DaggerMyComponent.builder().build();
myComponent.inject(this);
這樣就完成注入了,在Activity內的@Inject將可以透過剛剛建立的myComponent中的module裡的@Provide方法 或者其他@Inject標籤找到需要的物件。
老實講我認為Dagger入門門檻偏高,因為我也是看了無數篇文章才能使用這項工具,不過儘管如此我還是想介紹一下,這可以幫忙釐清許多觀念,了解到分工的重要性,在往後也能寫出更漂亮的code。