- 原文地址: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、前端、后端、区块链、产品、设计、人工智能等领域,想要查看更多优质译文请持续关注 掘金翻译计划、官方微博、知乎专栏。