同样的,在 dagger
的 component
中,你也可以通过 AndroidInjector<T>
去减少模板代码。
DaggerAppCompatActivity and DaggerFragment
在使用 dagger
的 fragment
或者 activity
中要记得调用 AndroidInjection.inject()
方法。 同样的,如果你想要在 v4
包里面的 fragment
中使用 Injection
,你应该让你的 activity
实现 HasSupportFragmentInject
接口并且重写 fragmentInjector
方法。
最近,我把这些相关代码移到 BaseActivity
和 BaseFragment
。因为与其在每个 activity
中声明这些,还不如把共同的代码放到基类里面。
于是我在研究 dagger
项目的时候发现 DaggerAppCompatActivity
、DaggerFragment
这些类正好是我所需要的。如果说 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
包的 Fragment
到 dagger
。所以如果你想在 v4.fragment
中使用注入,那么你应该在你的 AppComponent modules
中添加 AndroidSupportInjectionModule.class
。
我们改变了 AppComponent
的注入方式。那么 Application
类需要做什么改变。
跟 DaggerActivity
和 DaggerFragment
一样,我们也让 Application
类继承 DaggerApplication
类。
之前的 Application
类的代码如下:
最后
由于文章篇幅原因,我只把面试题列了出来,详细的答案,我整理成了一份PDF文档,这份文档还包括了还有 高级架构技术进阶脑图、Android开发面试专题资料,高级进阶架构资料 ,帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习。
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门,即可获取!