- 原文地址:New Android Injector with Dagger 2 — part 3
- 原文做者:Mert Şimşek
- 譯文出自:掘金翻譯計劃
- 本文永久連接:github.com/xitu/gold-m…
- 譯者:woitaylor
- 校對者:corresponding shengye102
若是你尚未閱讀(一)和(二),我建議你先閱讀它們。html
你可使用 DaggerActivity
,DaggerFragment
,DaggerApplication
來減小 Activity/Fragment/Application
類裏面的模板代碼。前端
一樣的,在 dagger
的 component
中,你也能夠經過 AndroidInjector<T>
去減小模板代碼。android
在使用 dagger
的 fragment
或者 activity
中要記得調用 AndroidInjection.inject()
方法。 一樣的,若是你想要在 v4
包裏面的 fragment
中使用 Injection
,你應該讓你的 activity
實現 HasSupportFragmentInject
接口而且重寫 fragmentInjector
方法。ios
最近,我把這些相關代碼移到 BaseActivity
和 BaseFragment
。由於與其在每一個 activity
中聲明這些,還不如把共同的代碼放到基類裏面。git
因而我在研究 dagger
項目的時候發現 DaggerAppCompatActivity
、DaggerFragment
這些類正好是我所須要的。若是說 Android
喜歡繼承,那麼咱們也能夠僞裝喜歡繼承 😛github
讓咱們看看這些類作了些神馬。後端
@Beta
public abstract class DaggerAppCompatActivity extends AppCompatActivity
implements HasFragmentInjector, HasSupportFragmentInjector {
@Inject DispatchingAndroidInjector<Fragment> supportFragmentInjector;
@Inject DispatchingAndroidInjector<android.app.Fragment> frameworkFragmentInjector;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
AndroidInjection.inject(this);
super.onCreate(savedInstanceState);
}
@Override
public AndroidInjector<Fragment> supportFragmentInjector() {
return supportFragmentInjector;
}
@Override
public AndroidInjector<android.app.Fragment> fragmentInjector() {
return frameworkFragmentInjector;
}
}
複製代碼
從上面的代碼能夠看出 DaggerAppCompatActivity
跟咱們本身寫的 Activity
並無多大的區別,因此可讓咱們的 Activity
以繼承 DaggerAppCompatActivity
的方式來減小模板代碼。api
DetailActivity
類以下:bash
public class DetailActivity extends AppCompatActivity implements HasSupportFragmentInjector, DetailView {
@Inject
DispatchingAndroidInjector<Fragment> fragmentDispatchingAndroidInjector;
@Inject
DetailPresenter detailPresenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
AndroidInjection.inject(this);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detail);
}
@Override
public void onDetailLoaded() {}
@Override
public AndroidInjector<Fragment> supportFragmentInjector() {
return fragmentDispatchingAndroidInjector;
}
}
複製代碼
讓咱們的 DetailActivity
繼承 DaggerAppCompatActivity
類,這樣咱們就不用讓 DetailActivity
類實現 HasSupportFragmentInjector
接口以及重寫方法了。app
public class DetailActivity extends DaggerAppCompatActivity implements DetailView {
@Inject
DetailPresenter detailPresenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detail);
}
@Override
public void onDetailLoaded() {}
}
複製代碼
如今,是否是更簡潔了。
看看還有哪些辦法可以減小模板代碼。我發現 AndroidInjector
可以幫助簡化 AppComponent
。你能夠經過閱讀 AndroidInjector
相關文檔來獲取相關信息。
下面是 AppComponent
類的代碼。
@Component(modules = {
AndroidInjectionModule.class,
AppModule.class,
ActivityBuilder.class})
public interface AppComponent {
@Component.Builder
interface Builder {
@BindsInstance Builder application(Application application);
AppComponent build();
}
void inject(AndroidSampleApp app);
}
複製代碼
build()
和 seedInstance()
方法已經在 AndroidInjector.Builder
抽象類中定義了,因此咱們的 Builder
類能夠經過繼承 AndroidInjection.Builder<Application>
來去掉上面代碼中 application()
和 build()
這兩個方法。
一樣的,AndroidInjector
接口中已經有 inject()
方法了。因此咱們能夠經過繼承 AndroidInjector<Application>
接口(接口是能夠繼承接口的)來刪除 inject()
方法。
那麼咱們簡化後的 AppComponent
接口的代碼以下:
@Component(modules = {
AndroidSupportInjectionModule.class,
AppModule.class,
ActivityBuilder.class})
interface AppComponent extends AndroidInjector<AndroidSampleApp> {
@Component.Builder
abstract class Builder extends AndroidInjector.Builder<AndroidSampleApp> {}
}
複製代碼
你有沒有意識到咱們的 modules
屬性也改變了?我從 @Component
註解的 modules
屬性中移除了 AndroidInjectionModule.class
而且添加了 AndroidSupportInjectionModule.class
。這是由於咱們使用的是支持庫(v4庫)的 Fragment
。而 AndroidInjectionModule
是用來綁定 app
包的 Fragment
到 dagger
。因此若是你想在 v4.fragment
中使用注入,那麼你應該在你的 AppComponent modules
中添加 AndroidSupportInjectionModule.class
。
咱們改變了 AppComponent
的注入方式。那麼 Application
類須要作什麼改變。
跟 DaggerActivity
和 DaggerFragment
同樣,咱們也讓 Application
類繼承 DaggerApplication
類。
以前的 Application
類的代碼以下:
public class AndroidSampleApp extends Application implements HasActivityInjector {
@Inject
DispatchingAndroidInjector<Activity> activityDispatchingAndroidInjector;
@Override
public void onCreate() {
super.onCreate();
DaggerAppComponent
.builder()
.application(this)
.build()
.inject(this);
}
@Override
public DispatchingAndroidInjector<Activity> activityInjector() {
return activityDispatchingAndroidInjector;
}
}
複製代碼
修改後代碼以下:
public class AndroidSampleApp extends DaggerApplication {
@Override
protected AndroidInjector<? extends AndroidSampleApp> applicationInjector() {
return DaggerAppComponent.builder().create(this);
}
}
複製代碼
你能夠從個人 GitHub 上獲取修改後的源碼。我沒有把這些代碼 merge
到主分支上,是由於我想在各個分支中保存 dagger
使用方式的歷史記錄。這樣讀者們就可以知道我是如何一步步簡化 dagger
的使用方式。
我並非說這是 dagger
的最優美的實踐方式。這只是我在本身項目中使用 dagger
的方式。若是喜歡的話,你也能夠在本身的項目中這樣使用。若是你實在不想讓本身的 Application
類繼承第三方的 Application
類就別這樣使用(你能夠把 DaggerApplication
的代碼拷貝到你本身的App類裏面,把 DaggerActivity/DaggerFragment
裏面的代碼拷貝到你本身的 BaseActivity/BaseFragment
中,若是你繼承的是 AppCompatActivity
就使用 DaggerAppCompatActivity
。 ),你高興就好。最後,若是大家有更好的建議還請多多指教。
掘金翻譯計劃 是一個翻譯優質互聯網技術文章的社區,文章來源爲 掘金 上的英文分享文章。內容覆蓋 Android、iOS、前端、後端、區塊鏈、產品、設計、人工智能等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃、官方微博、知乎專欄。