dagger2从入门到放弃
在大学时学过SSH,从那时知道spring的核心,就是IOC控制反转,听起来也是莫名其妙,当时也不知道有什么用,就明白一个DI依赖注入,当然spring在java上是很重要的内容,近段时间也用spring mvc来搭建一个网站,确实还蛮好玩的。
而dagger2则是android上的依赖注入手段,通过注释@Inject
就可以new创建出一个对象,而该对象里面所依赖的对象,都统统交给dagger2处理,dagger2不需要反射,是事先预编译的结果,可以在build里查看,简单的说我们不需要为创建对象苦恼。
定义
dagger2常用几个注释
@Component
@Module
@Provides
Application层
在Component里是为了将需要的对象公开接口,否则会在activity中用到application层的对象找不到
@Singleton
@Component(modules = AppModule.class)
public interface AppComponent {
RetrofitClient getRetrofitClient(); // 公开接口
}
App模块会提供公用的Application和RetrofitClient
@Module
public class AppModule {
Application app;
public AppModule(Application app) {
this.app = app;
}
@Provides
public Application providesApp() {
return app;
}
/**
* 创建一个Retrofit Service
*/
@Provides
public RetrofitClient provideService() {
return new RetrofitClient();
}
}
Activity层
Scope是为了保证对象与Activity生命周期
/**
* 作用域
* Created by 剑指锁妖塔 on 2016/4/7.
*/
@Scope
public @interface ActivityScope {
}
DemoComponent会依赖于AppComponent,modules模块会定义在DemoModule
@ActivityScope
@Component(modules = DemoModule.class, dependencies = AppComponent.class)
public interface DemoComponent {
DemoActivity inject(DemoActivity activity);
}
DemoActivity用到的DemoPresenter,将会由DemoModule来@Provides提供,在DemoPresenter里会用到RetrofitClient,这个参数就是从AppComponent依赖而来
@Module
public class DemoModule {
public DemoModule() {
}
@Provides
DemoPresenter providesPresenter(RetrofitClient client) {
return new DemoPresenter(client);
}
}
Presenter层
其实DemoPresenter在构造函数时@Inject也同样可以将RetrofitClient引入
/**
* demo的业务逻辑
* Created by 剑指锁妖塔 on 2016/6/20.
*/
public class DemoPresenter implements ViewPresenter<DemoViewImpl> {
DemoViewImpl viewImpl;
RetrofitClient client;
public DemoPresenter(RetrofitClient client) {
this.client = client;
}
@Override
public void setViewImpl(DemoViewImpl view) {
this.viewImpl = view;
}
public void test() {
client.getInstance(Api.class).getInfo()
.subscribeOn(Schedulers.newThread()).observeOn(AndroidSchedulers.mainThread())
.subscribe(s -> {
Logger.w(s);
viewImpl.getString(s);
}, r -> Logger.e(r.getMessage()));
}
}
使用
以上就是整个项目里dagger2的模块定义划分,然后就是如何在项目里依赖注入
app
在application里先建立一个AppComponent
public class App extends Application {
static AppComponent appComponent;
@Override
public void onCreate() {
super.onCreate();
appComponent = DaggerAppComponent.builder()
.appModule(new AppModule(this))
.build();
}
public static AppComponent getAppComponent() {
return appComponent;
}
}
activity
activity若想使用依赖注入,必需就让activity开始时就引入DaggerDemoComponent,否则无关联依赖必失败
public class DemoActivity extends AppCompatActivity implements DemoViewImpl {
@BindView(R.id.demo_id)
protected TextView pT;
@Inject
DemoPresenter presenter; // 依赖注入的对象
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_demo);
ButterKnife.bind(this);
DaggerDemoComponent.builder()
.appComponent(App.getAppComponent())
.demoModule(new DemoModule()).build().inject(this);
presenter.setViewImpl(this);
}
/**
* retrofitTest
*/
@OnClick(R.id.demo_btn)
void test() {
presenter.test(); // 使用该实例的方法
}
@Override
public void getString(String s) {
pT.setText(s);
}
}
源代码DaggerDemo
dagger2的原理在许多博客有详细说明源码分析,我这不入流就算了
学这个dagger2的过程中很容易从入门到放弃,像控制反转、依赖的内容是交由系统去处理,是确实比较难去看代码去理解,我在自己一个app里用这种依赖注入的框架,的确在模块化的解耦上有很大帮助,但会发现完成一组功能就要创建很多类,总得来说适合的才是最好的