注解是代码里的特殊标记,这些标记可以在编译、类加载、运行时被读取,并执行相应的处理。
注解分为:标准注解和元注解。
标准注解:
- @Override:对覆盖超类中的方法进行标记。
- @Deprecated:对不鼓励使用或者已过时的方法添加注解。
- @SuppressWarnings:选择性地取消特定代码段中的警告。
- @SafeVarargs:声明使用了可变长度参数的方法。
元注解:
- @Targe:注解所修饰的对象范围。
- @Inherited:表示注解可以被继承。
- @Documented:表示注解应该被JavaDoc工具记录。
- @Retention:声明注解的保留策略。
- @Repeatable:允许一个注解在同一声明类型(类、属性或方法)多次使用。
- 控制反转:IoC (Inversion of Control)
- 借助于"第三方"实现具有依赖关系的对象之间的解耦。
- 使原先多个耦合的对象现在全部依赖于Ioc容器,各对象之间不再互相依赖,实现了解耦的操作。
- 举例来说:对象A依赖于对象B,A在运行过程中需要B时就会主动创建B,控制权在对象A。现在,引入IoC容器之后,当A需要B时,IoC容器会主动创建一个对象B,注入到对象A需要的地方,此时对象A由主动变被动,控制权反转。
依赖注入:DI(Dependency Injection)
控制反转是指获得依赖对象的过程被反转。
依赖注入,是指IoC容器在运行期间,动态将某种依赖关系注入到对象中。
常用的依赖注入方式:
- 构造方法注入。
- Setter方法注入。
- 接口注入。
- Dagger2 是一个基于 JSR-330 (Java依赖注入) 标准的依赖注入框架,在编译期间自动生成代码,负责依赖对象的创建。
- 官网:https://github.com/google/dagger
- 添加依赖库:
api 'com.google.dagger:dagger:2.24'
annotationProcessor 'com.google.dagger:dagger-compiler:2.24'
- @Inject 和 @Conponent
//Tips.class 要被注入的类
import javax.inject.Inject;
public class Tips {
@Inject
public Tips() {
}
public String getTip() {
return "你获得了一个提示!";
}
}
/**
* MainActivityComponent.class
* 用于生产辅助类,(编译后产生辅助类)
* 建议命名:目标类名(被注入类)+Component
*/
import dagger.Component;
@Component
public interface MainActivityComponent {
void inject(MainActivity mainActivity);
}
/**
* MainActivity.class 部分
* 1处:@Inject标记需要注入的属性。
* 2处:调用注入。
*/
@Inject//1
Tips tips;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DaggerMainActivityComponent.create().inject(this);//2
tips.getTip();
}
- 情况1:使用第三方类库
//GsonModule.class
import com.google.gson.Gson;
import dagger.Module;
import dagger.Provides;
@Module
public class GsonModule {
@Provides
public Gson provideGson(){
return new Gson();
}
}
//GsonModule.class
import com.virtual.learnrxjava.GsonModule;
import com.virtual.learnrxjava.MainActivity;
import dagger.Component;
@Component(modules = GsonModule.class)
public interface MainActivityComponent {
void inject(MainActivity mainActivity);
}
- 情况2:需要注入的对象是抽象的
//其中SubClass.class 继承于 SuperClass.class
@Module
public class SubModule {
@Provides
public SuperClass getSubClass(){
return new SubClass();
}
}
- @Qualifier 是限定符,@Named 是 @Qualifier 的一种实现。
- @Named用法:
@Module
public class GsonModule {
@Provides
@Named("g1")
public Gson provideGsonA(){
return new Gson();
}
@Provides
@Named("g2")
public Gson provideGsonB(){
return new Gson();
}
}
//使用举例
@Injetc
public showJson(@Named("g1") Gson gson){
...
}
- @Named 传递的值只能是字符串;@Qualifier 更灵活,用于自定义注解。
- @Qualifier 用法:
//定义注解
//myGson1.class
@Qualifier
@Retention(RUNTIME)
public @interface myGson1{
}
//myGson2.class
@Qualifier
@Retention(RUNTIME)
public @interface myGson2{
}
@Module
public class GsonModule {
@Provides
@myGson1
public Gson provideGsonA(){
return new Gson();
}
@Provides
@myGson2
public Gson provideGsonB(){
return new Gson();
}
}
@Injetc
public showJson(@myGson1 Gson gson){
...
}
- @Scope:自定义注解。
- @Singleton:配合@Scope实现局部单例和全局单例。
- 局部单例的实现:
@Module
public class GsonModule {
@Singleton
@Provides
public Gson provideGson(){
return new Gson();
}
}
@Singleton
@Component(modules = GsonModule.class)
public interface MainActivityComponent {
void inject(MainActivity mainActivity);
}
- 全局单例的实现:
//定义注解
@Scope
@Retention(RUNTIME)
public @interface ApplicationScope{
}
@Module
public class GsonModule {
@ApplicationScope
@Provides
public Gson provideGson(){
return new Gson();
}
}
@ApplicationScope
@Component(modules = GsonModule.class)
public interface MainActivityComponent {
void inject(MainActivity mainActivity);
}
//创建App继承Application
import android.app.Application;
import android.content.Context;
public class App extends Application {
ActivityComponent activityComponent;
@Override
public void onCreate() {
super.onCreate();
activityComponent=DaggerActivityComponent.builder().build();
}
public static App get(Context context){
return (App)context.getApplicationContext();
}
ActivityComponent getActivityComponent(){
return activityComponent;
}
}
- 处理多Activity时可以:
@ApplicationScope
@Component(modules = GsonModule.class)
public interface ActivityComponent {
void inject(MainActivity activity);
void inject(SecondActivity activity);
}
- @Component 可以用 dependencies 依赖于其他Component。
//新建New.class
import javax.inject.Inject;
public class New {
@Inject
public New(){
}
public String msg(){
return "Hello!";
}
}
//新建NewModule.class
import dagger.Module;
import dagger.Provides;
@Module
public class NewModule {
@Provides
public New providerNew(){
return new New();
}
}
//新建NewComponent.class
import dagger.Component;
@Component(modules = NewModule.class)
public interface NewComponent {
New getNew();
}
@Component(modules = GsonModule.class,dependencies = NewComponent.class)
public interface ActivityComponent {
void inject(MainActivity activity);
void inject(SecondActivity activity);
}
//对应App.class修改
@Override
public void onCreate() {
super.onCreate();
activityComponent=DaggerActivityComponent.builder().
newComponent(DaggerNewComponent.create()).build();
}
- 在**@Inject** 的时候不初始化,而是使用时初始化,调用**.get()**方法获取实例。
//修改部分
@Inject
Lazy<Tips> tipsLazy;
...
Tips tipsExample = tipsLazy.get()
- Android 进阶之光