Android dagger的使用
官方讲解:https://developer.android.google.cn/training/dependency-injection/dagger-basics?hl=zh_cn
Google demo:https://github.com/android/architecture-samples
添加依赖库
//dagger2
implementation 'com.google.dagger:dagger:2.35'
annotationProcessor 'com.google.dagger:dagger-compiler:2.35'
// retrofit2
implementation 'com.squareup.retrofit2:retrofit:2.3.0'
implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
// okhttp3
implementation 'com.squareup.okhttp3:okhttp:3.8.0'
// log拦截器
implementation 'com.squareup.okhttp3:logging-interceptor:3.8.0'
// cookie管理
implementation 'com.github.franmontiel:PersistentCookieJar:v1.0.1'
创建实例提供者
Api
@Module
public class ApiModule {
@Provides
@Singleton
public ServiceApi provideServiceApi(Retrofit retrofit) {
return retrofit.create(ServiceApi.class);
}
@Provides
@Singleton
public Retrofit getRetrofit(OkHttpClient okHttpClient) {
Gson gson = new GsonBuilder()
// .setDateFormat("yyyy-MM-dd HH:mm:ss")
.registerTypeAdapter(Date.class, new JsonDeserializer<Date>() {
@Override
public Date deserialize(JsonElement element, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
String date = element.getAsString();
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
format.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
try {
Date date1 = format.parse(date);
return date1;
} catch (ParseException exp) {
exp.printStackTrace();
return null;
}
}
})
.create();
return new Retrofit.Builder()
// 集成RxJava处理
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
// 集成Gson转换器
.addConverterFactory(GsonConverterFactory.create(gson))
// 使用OkHttp Client
.client(okHttpClient)
// baseUrl总是以/结束,@URL不要以/开头
.baseUrl(AppConfig.API_SERVER_URL)
.build();
}
@Provides
@Singleton
public OkHttpClient okHttpClient(Cache cache, App application) {
HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
loggingInterceptor.setLevel(BuildConfig.DEBUG ? HttpLoggingInterceptor.Level.BODY : HttpLoggingInterceptor.Level.NONE);
ClearableCookieJar cookieJar =
new PersistentCookieJar(new SetCookieCache(), new SharedPrefsCookiePersistor(application.getApplicationContext()));
return new OkHttpClient.Builder()
.addInterceptor(authTokenInterceptor())
.addInterceptor(loggingInterceptor) // 添加日志拦截器
.addInterceptor(buildCacheInterceptor())
.cache(cache) // 设置缓存文件
.retryOnConnectionFailure(true) // 自动重连
.connectTimeout(15, TimeUnit.SECONDS)
.readTimeout(20, TimeUnit.SECONDS)
.writeTimeout(20, TimeUnit.SECONDS)
.cookieJar(cookieJar)
.build();
}
@Provides
@Singleton
public Cache getCache(App application) {
File cacheFile = new File(application.getCacheDir(), "networkCache");
// 创建缓存对象,最大缓存50m
return new Cache(cacheFile, 1024 * 1024 * 50);
}
private Interceptor authTokenInterceptor() {
return chain -> {
Request request = chain.request();
TimeZone timeZone = TimeZone.getDefault();
timeZone.setID("");
String tz2 = timeZone.getDisplayName(true, TimeZone.SHORT);
Request authRequest = request.newBuilder()
.header("timeZone", tz2)
.build();
return chain.proceed(authRequest);
};
}
private Interceptor buildCacheInterceptor() {
return chain -> {
Request request = chain.request();
// 无网络连接时请求从缓存中读取
if (!NetworkUtils.isConnected()) {
request = request.newBuilder()
.cacheControl(CacheControl.FORCE_CACHE).build();
}
// 响应内容处理:在线时缓存5分钟;离线时缓存4周
Response response = chain.proceed(request);
if (NetworkUtils.isConnected()) {
int maxAge = 300;
response.newBuilder()
.header("Cache-Control", "public, max-age=" + maxAge)
.removeHeader("Pragma") // 清除头信息,因为服务器如果不支持,会返回一些干扰信息,不清除下面无法生效
.build();
} else {
// 无网络时,设置超时为4周
int maxStale = 60 * 60 * 24 * 28;
response.newBuilder()
.header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
.removeHeader("Pragma")
.build();
}
return response;
};
}
}
- 根据需要创建其他实例提供者,比如OSS或者App
@Module
public class OSSModule {
@Provides
@Singleton
OSS provideOss(App app, ServiceApi api) {
final String[] endpoints = {"https://oss-cn-xxxxx.aliyuncs.com"};
OSSCustomSignerCredentialProvider provider = new OSSCustomSignerCredentialProvider() {
@Override
public String signContent(String content) {
String sign = null;
return sign;
}
};
ClientConfiguration conf = new ClientConfiguration();
conf.setConnectionTimeout(15 * 1000); // 连接超时,默认15秒
conf.setSocketTimeout(15 * 1000); // socket超时,默认15秒
conf.setMaxConcurrentRequest(5); // 最大并发请求书,默认5个
conf.setMaxErrorRetry(3); // 失败后最大重试次数,默认2次
return new OSSClient(app, endpoints[0], provider, conf);
}
}
@Module
public class ApplicationModule {
private App mApplication;
public ApplicationModule(App application) {
mApplication = application;
}
@Provides
@Singleton
App provideApplication() {
return mApplication;
}
@Provides
@ApplicationContext
@Singleton
Context provideContext() {
return mApplication;
}
}
- 组合的实例提供者
@Singleton
@Component(modules = {
ApplicationModule.class,
ApiModule.class,
OSSModule.class
})
public interface ApplicationComponent {
@ApplicationContext
Context context();
App application();
ServiceApi serviceApi();
OSS oss();
OkHttpClient okHttpClicent();
}
- 可选项,限定符
@Qualifier
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface ApplicationContext {
}
- 可选项,使用范围
@Documented
@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface PerActivity {
}
@Documented
@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface PerFragment {
}
@Documented
@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface PerService {
}
创建注入器
每用一个,都要在这里加一个注入接口
@PerActivity
@Component(dependencies = {ApplicationComponent.class})
public interface ActivityComponent {
void inject(MainActivity mainActivity);
}
@PerFragment
@Component(dependencies = {ApplicationComponent.class})
public interface FragmentComponent {
void inject(HomeFragment homeFragment);
}
注入
可在基类中封装,也可以单独在每个界面注入
public class App extends Application{
private ApplicationComponent mApplicationComponent;
public ApplicationComponent getApplicationComponent() {
if (mApplicationComponent == null) {
mApplicationComponent = DaggerApplicationComponent.builder()
.applicationModule(new ApplicationModule(this))
.apiModule(new ApiModule())
.oSSModule(new OSSModule())
.build();
}
return mApplicationComponent;
}
}
基类封装
private ActivityComponent mActivityComponent;
public ActivityComponent getActivityComponent() {
if (mActivityComponent == null) {
mActivityComponent = DaggerActivityComponent.builder()
.applicationComponent(App.getApp().getApplicationComponent())
.build();
}
return mActivityComponent;
}
@Override
@CallSuper
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
inject(getActivityComponent());
}
protected void inject(ActivityComponent activityComponent) {
// 子类具体实现dagger注入
}
子类具体注入
@Override
protected void inject(ActivityComponent activityComponent) {
activityComponent.inject(this);
}
结合mvp
- 基类
// 基类Activity
public abstract class BaseActivity<P extends BaseActivityPresenter>{
@Inject
protected P mPresenter;
@Override
@CallSuper
protected void onCreate(@Nullable Bundle savedInstanceState) {
if (mPresenter != null) {
mPresenter.attachView(this);
}
}
@Override
@CallSuper
protected void onDestroy() {
if (mPresenter != null) {
mPresenter.detachView();
}
}
}
// 基类Presenter
public abstract class BaseActivityPresenter<T extends BaseActivity> {
protected T mActivity;
public void attachView(T activity) {
mActivity = activity;
}
public void detachView() {
if (mActivity != null) {
mActivity = null;
}
}
}
- 子类
public class MainActivity extends BaseActivity<MainPresenter> {
mPresenter.xxxApi()
private onXxxApiOk(){
}
}
public class MainPresenter extends BaseActivityPresenter<MainActivity> {
private ServiceApi mApi;
@Inject
public MainPresenter(ServiceApi api) {
mApi = api;
}
public void xxxApi(String xxxId) {
mApi.xxxxxxx(xxxId)
.xxx// rxjava 和 retrofit那一套
.subscribe(new RxSubscriber<BaseHttpEntity<XXXEntity>>() {
@Override
protected void onSuccess(BaseHttpEntity<XXXEntity> response) {
mActivity.onXxxApiOk(response.getDetails());
}
});
}
}