[译] 全新 Android 注入器 _ Dagger 2(三)(2)

同样的,在 daggercomponent 中,你也可以通过 AndroidInjector<T> 去减少模板代码。

DaggerAppCompatActivity and DaggerFragment

在使用 daggerfragment 或者 activity 中要记得调用 AndroidInjection.inject() 方法。 同样的,如果你想要在 v4 包里面的 fragment 中使用 Injection,你应该让你的 activity 实现 HasSupportFragmentInject 接口并且重写 fragmentInjector 方法。

最近,我把这些相关代码移到 BaseActivityBaseFragment。因为与其在每个 activity 中声明这些,还不如把共同的代码放到基类里面。

于是我在研究 dagger 项目的时候发现 DaggerAppCompatActivityDaggerFragment 这些类正好是我所需要的。如果说 Android 喜欢继承,那么我们也可以假装喜欢继承 😛

让我们看看这些类做了些神马。

@Beta
public abstract class DaggerAppCompatActivity extends AppCompatActivity
implements HasFragmentInjector, HasSupportFragmentInjector {

@Inject DispatchingAndroidInjector supportFragmentInjector;
@Inject DispatchingAndroidInjector<android.app.Fragment> frameworkFragmentInjector;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
AndroidInjection.inject(this);
super.onCreate(savedInstanceState);
}

@Override
public AndroidInjector supportFragmentInjector() {
return supportFragmentInjector;
}

@Override
public AndroidInjector<android.app.Fragment> fragmentInjector() {
return frameworkFragmentInjector;
}
}

从上面的代码可以看出 DaggerAppCompatActivity 跟我们自己写的 Activity 并没有多大的区别,所以可以让我们的 Activity 以继承 DaggerAppCompatActivity 的方式来减少模板代码。

DetailActivity 类如下:

public class DetailActivity extends AppCompatActivity implements HasSupportFragmentInjector, DetailView {

@Inject
DispatchingAndroidInjector 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 supportFragmentInjector() {
return fragmentDispatchingAndroidInjector;
}
}

让我们的 DetailActivity 继承 DaggerAppCompatActivity 类,这样我们就不用让 DetailActivity 类实现 HasSupportFragmentInjector 接口以及重写方法了。

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() {}
}

现在,是不是更简洁了。

DaggerApplication, AndroidInjector, AndroidSupportInjectionModule

看看还有哪些办法能够减少模板代码。我发现 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 {
@Component.Builder
abstract class Builder extends AndroidInjector.Builder {}
}

你有没有意识到我们的 modules 属性也改变了?我从 @Component 注解的 modules 属性中移除了 AndroidInjectionModule.class 并且添加了 AndroidSupportInjectionModule.class。这是因为我们使用的是支持库(v4库)的 Fragment。而 AndroidInjectionModule 是用来绑定 app 包的 Fragmentdagger。所以如果你想在 v4.fragment 中使用注入,那么你应该在你的 AppComponent modules 中添加 AndroidSupportInjectionModule.class

我们改变了 AppComponent 的注入方式。那么 Application 类需要做什么改变。

DaggerActivityDaggerFragment 一样,我们也让 Application 类继承 DaggerApplication 类。

之前的 Application 类的代码如下:

最后

由于文章篇幅原因,我只把面试题列了出来,详细的答案,我整理成了一份PDF文档,这份文档还包括了还有 高级架构技术进阶脑图、Android开发面试专题资料,高级进阶架构资料 ,帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习。
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值