Android Dagger2的基本使用
官网地址:https://google.github.io/dagger/
github地址:https://github.com/google/dagger
Dagger2作用:对象的管理,降低程序的耦合。
Dagger的常用注解:
@Inject
1.构造器注入(有多个构造器,只能标注其中一个)
2.属性注入(被注入的属性不能用private修饰)
3.方法注入(依赖需要this对象的时刻可以提供安全的this对象)
@Component
Dagger2是通过component来完成依赖注入的,一般定义component通常使用接口定义,用@Component注解。
两种定义方法:
1、void inject(目标类obj)
Dagger2会从目标类开始查找@Inject注解,自动生成依赖注入的代码,调用inject可完成依赖的注入。
2、Object getObj();
这种方式一般为其他Component提供依赖。
@Module
@module标记在类的上面
在@Component中指定Module(@Component = obj.class)
具体来说:此注解里面全是方法,用于对外提供对象,自己定义方法,方法上使用@Provides。自定义一个类,以Module结尾,用@Module注解。
@Provodes
@Provodes标记在方法的上面
@Qualifier和@Named
@Qualifier是限定符,而@Named则是基于String的限定符
当我有两个相同的依赖(都继承某一个父类或者都是先某一个接口)可以提供给高层时,那么程序就不知道我们到底要提供哪一个依赖,因为它找到了两个。这时候我们就可以通过限定符为两个依赖分别打上标记,指定提供某个依赖。
@Qualifier不是直接注解在属性上的,而是用来自定义注解的。
不论是@Qualifier还是@Named必须成对出现,否则报错。
@PerActivity
限定对象的生命周期和Activity一样。一般应用于自定义的Component上。
@Singleton
标记为单例模式,如果在自定义Module中使用了此注解,在自定义的Component上也要使用该注解。
一个简单的DaggerDemo
基本使用
1、在对应的类添加@Inject注解
package com.hzy.dragerproject;
import javax.inject.Inject;
public class Person {
private String name;
private int age;
private int sex;
@Inject //此处在构造函数添加注解
public Person() {
}
@Override
public String toString() {
return "Person{" +
"name='" + "hzy" + '\'' +
", age=" + 18 +
", sex=" + 1 +
'}';
}
}
2、创建Component通过@Component()内的inject方法关联到对应的类
package com.hzy.dragerproject;
import dagger.Component;
@Component()
public interface MainComponent {
void inject(MainActivity mainActivity);
}
3、在对应内里面调用(通过@Inject调用)
package com.hzy.dragerproject;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import javax.inject.Inject;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
@Inject
Person person;//此处调用
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 这一句代码是完成依赖注入的关键
DaggerMainComponent.builder()
.build()
.inject(this);
Log.e(TAG, person.toString());// 执行注入对象方法
}
}
此处特别注意DaggerMainComponent需要Rebuild Project才能生成,按Ctr+F9重新编译即可。
当我们需要关联多个的时候可以在DaggerMainComponent内继续添加
package com.hzy.dragerproject;
import dagger.Component;
@Component()
public interface MainComponent {
void inject(MainActivity mainActivity);
void inject(Main2Activity main2Activity);
}
然后再对应的类里面调用即可。
此处为微阅app内Dagger2使用代码
1、在Application内DaggerApplicationComponent
public class MyApp extends LitePalApplication {
private ApplicationComponent mApplicationComponent;
private static MyApp sMyApp;
public static int width = 0;
public static int height = 0;
@Override
public void onCreate() {
super.onCreate();
sMyApp = this;
BGASwipeBackManager.getInstance().init(this);
mApplicationComponent = DaggerApplicationComponent.builder()//调用DaggerApplicationComponent
.applicationModule(new ApplicationModule(this))
.httpModule(new HttpModule())
.build();
LitePal.initialize(this);
width = ContextUtils.getSreenWidth(MyApp.getContext());
height = ContextUtils.getSreenHeight(MyApp.getContext());
}
public static MyApp getInstance() {
return sMyApp;
}
public ApplicationComponent getApplicationComponent() {
return mApplicationComponent;
}
}
2、通过Component和modules关联到ApplicationModule.class和HttpModule.class
@Component(modules = {ApplicationModule.class,HttpModule.class})
public interface ApplicationComponent {
MyApp getApplication();
NewsApi getNetEaseApi();
JanDanApi getJanDanApi();
Context getContext();
}
3、ApplicationModule内为我们提供上下文
@Module
public class ApplicationModule {
private Context mContext;
public ApplicationModule(Context context) {
this.mContext = context;
}
@Provides
MyApp provideApplication() {
return (MyApp) mContext.getApplicationContext();
}
@Provides
Context provideContext() {
return mContext;
}
}
4、HttpModule为我们提供封装好的网络请求
@Module
public class HttpModule {
@Provides
OkHttpClient.Builder provideOkHttpClient() {
// 指定缓存路径,缓存大小100Mb
Cache cache = new Cache(new File(MyApp.getContext().getCacheDir(), "HttpCache"),
1024 * 1024 * 100);
return new OkHttpClient().newBuilder().cache(cache)
.retryOnConnectionFailure(true)
.addInterceptor(RetrofitConfig.sLoggingInterceptor)
.addInterceptor(RetrofitConfig.sRewriteCacheControlInterceptor)
.addNetworkInterceptor(RetrofitConfig.sRewriteCacheControlInterceptor)
.connectTimeout(10, TimeUnit.SECONDS);
}
// @Provides
// Retrofit.Builder provideBuilder(OkHttpClient okHttpClient) {
// return new Retrofit.Builder()
// .addConverterFactory(GsonConverterFactory.create())
// .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
// .client(okHttpClient);
// }
@Provides
NewsApi provideNetEaseApis(OkHttpClient.Builder builder) {
builder.addInterceptor(RetrofitConfig.sQueryParameterInterceptor);
Retrofit.Builder retrofitBuilder = new Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.client(builder.build());
return NewsApi.getInstance(retrofitBuilder
.baseUrl(ApiConstants.sIFengApi)
.build().create(NewsApiService.class));
}
@Provides
JanDanApi provideJanDanApis(OkHttpClient.Builder builder) {
Retrofit.Builder retrofitBuilder = new Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.client(builder.build());
return JanDanApi.getInstance(retrofitBuilder
.baseUrl(ApiConstants.sJanDanApi)
.build().create(JanDanApiService.class));
}
}
参考链接:
https://blog.csdn.net/Jet_Green/article/details/80996657
https://github.com/Will-Ls/WeiYue