前言
本篇是以 dagger2 在 mvp 中的应用开发为例。如果还有不理解dagger2的,可以先看一下我之前发的通俗易懂的dagger2-入门篇或者先了解一下依赖倒置原则,当然也可以直接开干
项目结构
先看一下项目结构图:
- 包结构从上到下依次
- application
放置项目Application
基类,可以在onCreate()
初始化一些全局实例。 - contract
mvp中担任链接view
和model
- di
- component
主要用于关联@Module标注的类和Activity及Fragment的子类。 - module
用于对外提供对象,一般可在@Module标注的类中添加自定义方法,方法标注@Provides,方法体中可用来做一些实例化操作等。
- component
- model
mvp中的model
,这里我是用来放实体类和网络请求 - presenter
mvp中的presenter
,为了方便我在里面进行了网络请求并回调数据到view
- ui
- view
mvp中的view
,放置通用的回调方法
- view
实战
一般写dagger2我都是先写好module,先看看包 di -> module
中的代码:
前期准备
@Module
public class NetworkModule {
@Singleton
@Provides
public GankService provideGankService() {
OkHttpClient.Builder httpClientBuilder = new OkHttpClient.Builder();
//设置超时时间
httpClientBuilder.connectTimeout(15 * 1000, TimeUnit.MILLISECONDS);
httpClientBuilder.writeTimeout(15 * 1000, TimeUnit.MILLISECONDS);
httpClientBuilder.readTimeout(15 * 1000, TimeUnit.MILLISECONDS);
return new Retrofit
.Builder()
.client(httpClientBuilder.build())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(GankService.BASE_URL)
.build()
.create(GankService.class);
}
}
比较简单,返回一个GankService接口对象,注意三个注解:
- @Module
用于对外提供对象,一般可在@Module标注的类中添加自定义方法,方法标注@Provides,方法体中可用来做一些实例化操作等。
- @Provides
配合@Module一起使用,@Provides用于标记方法,表示可以通过这个方法获取一个对象,一般用于自定义类中。
- @Singleton
dagger 2中的单例模式,@Module类中使用了,@Component中也要使用。
这里的NetworkModule类我只是用作一个依赖,我们可以在 AppComponent去引用它,在这之前再看看AppModule的代码:
@Module
public class AppModule {
private Application mApplication;
public AppModule(Application application) {
mApplication = application;
}
@Singleton
@Provides
public Application provideApplication() {
return mApplication;
}
}
这里没有多大用处,只是在为了后期能在全局调用Application基类对象,最后看看AppComponent的代码:
@Singleton
@Component(modules = {AppModule.class, NetworkModule.class})
public interface AppComponent {
Application getApplition();
GankService getGankService();
}
- @Component
主要用于关联@Module标注的类和Activity及Fragment的子类。
在Application基类App中调用
public class App extends Application {
private AppComponent mAppComponent;
private static App sApp;
@Override
public void onCreate() {
super.onCreate();
sApp = this;
mAppComponent = DaggerAppComponent.builder()
.appModule(new AppModule(this))
.networkModule(new NetworkModule())
.build();
}
public static App getApp() {
return sApp;
}
public AppComponent getAppComponent() {
return mAppComponent;
}
}
在这之前记得先在as
菜单栏中Build -> Rebuild Project
,最后不要忘了在AndroidMainifest.xml
application
节点下加上基类android:name=".application.App"
如何在Activity or Fragment中调用呢
我写了一个gank.io测试用例,前面我直接贴代码:
contract -> GankContract
public interface GankContract {
interface View extends BaseView {
void loadGankList(List<GankEntity> list);
}
interface Presenter {
void getGank(String type, int count, int page);
}
}
di -> GankModule
@Module
public class GankModule {
private GankContract.View mView;
public GankModule(GankContract.View view) {
mView = view;
}
@ActivityScope
@Provides
public GankContract.View provideView() {
return mView;
}
}
@ActivityScope
是我自定义的一个注解类
@Scope
public @interface ActivityScope {
}
- @Scope
Scopes可是非常的有用,Dagger2可以通过自定义注解限定注解作用域。
注解类在kotlin
中的写法:
@Scope
annotation class ActivityScope
di -> component
@Component(modules = {GankModule.class}, dependencies = {AppComponent.class})
public interface GankComponent {
void inject(MainActivity mainActivity);
}
dagger2具体代码就这么多了,应该算比较好理解的������
下面就是具体使用的代码了
MainActivity.class
public class MainActivity extends AppCompatActivity implements GankContract.View {
private static final String TAG = "MainActivity";
@Inject
GankPresenter mPresenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DaggerGankComponent.builder()
.appComponent(App.getApp().getAppComponent())
.gankModule(new GankModule(this))
.build()
.inject(this);
mPresenter.getGank("Android", 10, 1);
}
@Override
public void loadGankList(List<GankEntity> list) {
for (GankEntity entity : list) {
Log.d(TAG, "loadGankList: " + entity.toString());
}
}
}
presenter -> GankPresenter
public class GankPresenter implements GankContract.Presenter {
private GankContract.View mView;
private GankService mGankService;
@Inject
public GankPresenter(GankContract.View view, GankService gankService) {
mView = view;
mGankService = gankService;
}
@Override
public void getGank(String type, int count, int page) {
mGankService.getGankList(type, count, page)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<HttpResult<GankEntity>>() {
@Override
public void accept(HttpResult<GankEntity> gankEntityHttpResult) throws Exception {
mView.loadGankList(gankEntityHttpResult.getResults());
}
});
}
}
主要代码就这么多了,如果还有什么问题的话可以在下方留言,谢谢