Dagger2的简单使用

Dagger2的简单使用

文章目录

  • Dagger2的简单使用
    • 1.预备知识
      • 1.1 注解概念
      • 1.2 控制反转与依赖注入概念
    • 2.Dagger2的使用
      • 2.1 基本使用方法
      • 2.2 @Module 和 @Provides
      • 2.3 @Named 和 @Qualifier
      • 2.4 @Singleton 和 @Scope
      • 2.5 @Component 的 dependencies
      • 2.6 懒加载
    • 3.参考资料

1.预备知识

1.1 注解概念

  • 注解是代码里的特殊标记,这些标记可以在编译、类加载、运行时被读取,并执行相应的处理。

  • 注解分为:标准注解元注解

  • 标准注解

    • @Override:对覆盖超类中的方法进行标记。
    • @Deprecated:对不鼓励使用或者已过时的方法添加注解。
    • @SuppressWarnings:选择性地取消特定代码段中的警告。
    • @SafeVarargs:声明使用了可变长度参数的方法。
  • 元注解

    • @Targe:注解所修饰的对象范围。
    • @Inherited:表示注解可以被继承。
    • @Documented:表示注解应该被JavaDoc工具记录。
    • @Retention:声明注解的保留策略。
    • @Repeatable:允许一个注解在同一声明类型(类、属性或方法)多次使用。

1.2 控制反转与依赖注入概念

  • 控制反转:IoC (Inversion of Control)
  • 借助于"第三方"实现具有依赖关系的对象之间的解耦。
  • 使原先多个耦合的对象现在全部依赖于Ioc容器,各对象之间不再互相依赖,实现了解耦的操作。
  • 举例来说:对象A依赖于对象B,A在运行过程中需要B时就会主动创建B,控制权在对象A。现在,引入IoC容器之后,当A需要B时,IoC容器会主动创建一个对象B,注入到对象A需要的地方,此时对象A由主动变被动,控制权反转。

  • 依赖注入:DI(Dependency Injection)

  • 控制反转是指获得依赖对象的过程被反转

  • 依赖注入,是指IoC容器在运行期间,动态将某种依赖关系注入到对象中。

  • 常用的依赖注入方式:

    • 构造方法注入。
    • Setter方法注入。
    • 接口注入。

2.Dagger2的使用

  • Dagger2 是一个基于 JSR-330 (Java依赖注入) 标准的依赖注入框架,在编译期间自动生成代码,负责依赖对象的创建。
  • 官网:https://github.com/google/dagger

2.1 基本使用方法

  • 添加依赖库:
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();
}

2.2 @Module 和 @Provides

  • 情况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();
    }
}

2.3 @Named 和 @Qualifier

  • @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){
    ...
}

2.4 @Singleton 和 @Scope

  • @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);
}

2.5 @Component 的 dependencies

  • @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();
    }

2.6 懒加载

  • 在**@Inject** 的时候不初始化,而是使用时初始化,调用**.get()**方法获取实例。
//修改部分
@Inject
Lazy<Tips> tipsLazy;

...
    
    Tips tipsExample = tipsLazy.get()

3.参考资料

  • Android 进阶之光

你可能感兴趣的:(Android学习笔记,#,Android基础知识)