在基础和进阶两篇文章中,讨论很多的理论知识,不知道你们怎么样,反正我是有点懵逼了,程序猿么,终归是要垒代码。来吧,我们用代码说话,看一看Dagger2到底是怎么个用法。
本文代码地址 Dagger2 示例 app-mvp-dagger2
示例中采用了MVP架构,使用Retrofit进行网络通信,并融入了 Rxjava RxBus 等。Dagger2 使用示例 在 app-mvp-dagger2 分支,请自行chekcout。
依赖标注
@Inject 标注
- @Inject 注解 BaseActivity 和 BaseFragment 的 Presenter 实例。
|
|
|
|
- @Inject标注依赖构造函数
|
|
|
|
@Moudle 工厂类
AppModule 提供全局依赖实例
123456789101112131415161718192021public class AppModule {private final ArchiApplication application;public AppModule(ArchiApplication application){this.application = application;}ArchiApplication provideApplicationContext(){return application;}RetrofitHelper provideRetrofitHelper(RepositoriesService repositoriesService, UserInfoService userInfoService){return new RetrofitHelper(repositoriesService, userInfoService);}}ActivityModule 为 Activity 提供 this 实例
123456789101112public class ActivityModule {private Activity mActivity;public ActivityModule(Activity activity) {this.mActivity = activity;}public Activity provideActivity() {return mActivity;}}FragmentModule 为 Fragment 提供 Activity 实例
123456789101112public class FragmentModule {private Fragment fragment;public FragmentModule(Fragment fragment) {this.fragment = fragment;}public Activity provideActivity() {return fragment.getActivity();}}
Component组织
Component 是依赖和被依赖的的桥梁,注入依赖。
AppComponent
- 定义 AppComponent 接口 ,@Singleton 标注,增加可读性
|
|
- 创建 AppComponent 单例1234567891011121314public class ArchiApplication extends Application {public static AppComponent appComponent;public static AppComponent getAppComponent(){if (appComponent == null) {appComponent = DaggerAppComponent.builder().appModule(new AppModule(mInstance)).httpModule(new HttpModule()).build();}return appComponent;}}
ActivityComponent
自定义 ActivityScope 注解
1234(RetentionPolicy.RUNTIME)public ActivityScope {}定义 ActivityComponent 使用 @ActivityScope 标注
1234567(dependencies = AppComponent.class,modules = ActivityModule.class)public interface ActivityComponent {Activity getActivity();void inject(RepositoryActivity repositoryActivity);}@ActivityScope 标注 Module 中的依赖实例提供方法
12345public Activity provideActivity() {return mActivity;}Build ActivityComponent实例
123456789101112public abstract class BaseActivity<T extends BasePresenter> extends SupportActivity implements BaseView {...protected ActivityComponent getActivityComponent(){return DaggerActivityComponent.builder()// 添加依赖 component.appComponent(ArchiApplication.getAppComponent()).activityModule(new ActivityModule(this)).build();}}注入实例
12345678public class RepositoryActivity extends BaseActivity<RepositoryPresenter> implements RepositoryContract.View{...protected void initInject() {getActivityComponent().inject(this);}...}
FragmentComponent
自定义 FragmentComponent 注解
1234(RetentionPolicy.RUNTIME)public FragmentScope {}定义 FragmentComponent 使用 @FragmentScope 标注
12345678(dependencies = AppComponent.class,modules = FragmentModule.class)public interface FragmentComponent {Activity getActivity();void inject(MainFragment mainFragment);}@FragmentScope 标注 Module 中的依赖实例提供方法
12345public Activity provideActivity() {return fragment.getActivity();}Build FragmentComponent
123456789101112public abstract class BaseFragment<T extends BasePresenter> extends SupportFragment implements BaseView {...protected FragmentComponent getFragmentComponent(){return DaggerFragmentComponent.builder()// 添加依赖 component.appComponent(ArchiApplication.getAppComponent()).fragmentModule(new FragmentModule(this)).build();}}注入实例
12345678public class MainFragment extends BaseFragment<MainPresenter> implements MainContract.View {...protected void initInject() {getFragmentComponent().inject(this);}...}
RetrofitHelper 注入流程
MainPresenter 和 RepositoryPresenter 的构造函数中,有一个参数为 RetrofitHelper,根据Dagger2的注入流程,我们可以知道,RetrofitHelper会优先创建注入。
在 AppComponent 中管理的 Modules 中有一个 HttpModule,该 Module 主要作用是提供网络访问实例。
我们来看一下 RetrofitHelper 的注入流程。
- Presenter 的构造函数参数为 RetrofitHelper,所以 RetrofitHelper 会优先创建。
RetrofitHelper 构造函数参数为网络访问实例 RepositoriesService, UserInfoService。
1234public RetrofitHelper(RepositoriesService repositoriesService, UserInfoService userInfoService){this.repositoriesService = repositoriesService;this.userInfoService = userInfoService;}RepositoriesService 和 UserInfoService 实例由 HttpModule 提供
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071public class HttpModule {/*** 提供builder* */Retrofit.Builder provideRetrofitBuilder (){return new Retrofit.Builder();}OkHttpClient.Builder provideOkHttpClientBuilder(){return new OkHttpClient.Builder();}/*** 提供客户端* */Retrofit provideRepositoriesRetrofit(Retrofit.Builder builder,OkHttpClient client){return createRetrofit(builder, client, RepositoriesService.HOST);}Retrofit provideUserInfoRetrofit(Retrofit.Builder builder,OkHttpClient client){return createRetrofit(builder, client, RepositoriesService.HOST);}OkHttpClient provideClient(OkHttpClient.Builder builder) {return builder.connectTimeout(60000L, TimeUnit.MILLISECONDS).readTimeout(60000L, TimeUnit.MILLISECONDS).writeTimeout(60000L, TimeUnit.MILLISECONDS).build();}/*** 提供API* */RepositoriesService provideRepositoriesService(@RespositoriesUrl Retrofit retrofit){return retrofit.create(RepositoriesService.class);}UserInfoService provideUserInfoService(@UserInfoUrl Retrofit retrofit){return retrofit.create(UserInfoService.class);}private Retrofit createRetrofit(Retrofit.Builder builder, OkHttpClient client, String host) {return builder.baseUrl(host).client(client).addCallAdapterFactory(RxJavaCallAdapterFactory.create()).addConverterFactory(GsonConverterFactory.create()).build();}}
RetrofitHelper 完成创建后由 AppComponent 注入,为全局单一实例。
@Qualifier 使用
@Qualifier 的作用是使 Dagger2 避免依赖混乱。
定义 Qualifier 以 RespositoriesUrl 为例。
12345(RetentionPolicy.RUNTIME)public RespositoriesUrl {}使用 @RespositoriesUrl 标注依赖实例提供方法,该方法和其他方法的返回相同。
123456Retrofit provideRepositoriesRetrofit(Retrofit.Builder builder,OkHttpClient client){return createRetrofit(builder, client, RepositoriesService.HOST);}使用 @RespositoriesUrl 标注 provideRepositoriesRetrofit 的返回值
12345RepositoriesService provideRepositoriesService(@RespositoriesUrl Retrofit retrofit){return retrofit.create(RepositoriesService.class);}