📌  相关文章
📜  如何在 Android 应用中使用 Dagger 库?(1)

📅  最后修改于: 2023-12-03 15:24:06.850000             🧑  作者: Mango

如何在 Android 应用中使用 Dagger 库?

Dagger是一个开源的依赖注入框架,可用于Android和Java应用程序。在Android应用程序中,使用Dagger可以轻松管理应用程序中的依赖关系,使代码更加模块化、可维护和可测试。

安装

首先,在项目中使用Gradle构建添加Dagger库的依赖项:

dependencies {
   implementation 'com.google.dagger:dagger:2.x'
   annotationProcessor 'com.google.dagger:dagger-compiler:2.x'
}

其中,x是指Dagger库的版本号。

基本使用
  1. 创建一个Module类,用于提供依赖
@Module
public class MyModule {
    @Provides
    public MyDependency provideMyDependency() {
        return new MyDependencyImpl();
    }
}

其中,@Provides用于标记提供依赖的方法,MyDependency是需要提供的依赖类型,MyDependencyImpl是依赖的实现类。

  1. 创建一个Component类,用于连接依赖
@Component(modules = {MyModule.class})
public interface MyComponent {
    void inject(MyActivity activity);
}

其中,@Component用于标记连接依赖的类,modules指定需要连接的Module类,inject方法用于将依赖注入到目标类中。

  1. 在目标类中注入依赖
public class MyActivity extends AppCompatActivity {
    @Inject
    MyDependency myDependency;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        DaggerMyComponent.create().inject(this);
    }
}

其中,@Inject用于标记需要注入依赖的属性,在onCreate方法中,通过DaggerMyComponent.create().inject(this)将依赖注入到目标类中。

高级使用

在实际应用开发中,可能需要注入多个依赖,或者需要管理Scope等问题。在这种情况下,Dagger还提供了更加高级的使用方式。

Subcomponent

可以使用Subcomponent创建子组件,并将它们绑定到父组件中的一个或多个Module。

@Singleton
@Component(modules = {ParentModule.class})
public interface ParentComponent {
    ChildComponent createChildComponent(ChildModule childModule);
}

@Subcomponent(modules = {ChildModule.class})
public interface ChildComponent {
    void inject(ChildActivity childActivity);
}

@Module
public class ParentModule {
    @Provides
    @Singleton
    public MyDependency provideMyDependency() {
        return new MyDependencyImpl();
    }
}

@Module
public class ChildModule {
    private final ChildActivity childActivity;

    public ChildModule(ChildActivity childActivity) {
        this.childActivity = childActivity;
    }

    @Provides
    @ActivityScope
    public MyOtherDependency provideMyOtherDependency() {
        return new MyOtherDependencyImpl(childActivity);
    }
}

public class ChildActivity extends AppCompatActivity {
    @Inject
    MyDependency myDependency;

    @Inject
    MyOtherDependency myOtherDependency;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_child);

        ParentComponent parentComponent = DaggerParentComponent.create();
        ChildComponent childComponent = parentComponent.createChildComponent(new ChildModule(this));
        childComponent.inject(this);
    }
}
Qualifier

有时会有多个相同类型的依赖需要注入,但这些依赖价格或者类型不同,这时就可以使用@Qualifier进行区分。

public interface MyComponent {
    @Named("userName")
    String provideUserName();

    @Named("password")
    String providePassword();
}

@Module
public class MyModule {
    @Provides
    @Named("userName")
    public String provideUserName() {
        return "JohnDoe";
    }

    @Provides
    @Named("password")
    public String providePassword() {
        return "password";
    }
}

在注入时,可以使用@Named区分需要的依赖。

public class MainActivity extends AppCompatActivity {
    @Inject
    @Named("userName")
    String userName;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        DaggerMyComponent.create().inject(this);
    }
}
Scope

通过使用@Scope,可以在一个组件中定义一个Scope,并且在提供依赖时为每个依赖创建一个实例。

@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface ActivityScope {
}

@Module
public class MyModule {
    @Provides
    @ActivityScope
    public MyDependency provideMyDependency() {
        return new MyDependencyImpl();
    }
}

@Component(modules = {MyModule.class})
@ActivityScope
public interface MyComponent {
    void inject(MyActivity activity);
}

public class MainActivity extends AppCompatActivity {
    @Inject
    MyDependency myDependency1;

    @Inject
    MyDependency myDependency2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        DaggerMyComponent.create().inject(this);
    }
}

其中,@Scope用于声明Scope,可以在Module和Component中使用。在MyModule中,使用@ActivityScope声明提供的依赖需要在同一Activity中共享实例。在MyComponent中,使用@ActivityScope声明Component创建的所有依赖都可以共享该实例。

注意:在使用自定义Scope时,需要保证该Scope是在运行时保持不变的,如果Component中声明的Scope与Module中声明的Scope不一致,会报错。

总结

Dagger是一个非常强大的依赖注入框架,使用Dagger可以简化Android应用程序中的依赖管理。在开发过程中,根据需求灵活地运用Dagger的高级用法,可以使代码更加模块化、可维护和可测试。