如何使用 Dagger ?如何配置 Dagger 以在我的 Android 项目中工作?
我想在我的 Android 项目中使用 Dagger,但我觉得它很困惑。
编辑:Dagger2 也从 2015 年 04 月 15 日开始发布,它更令人困惑!
[这个问题是一个“ stub ”,当我更多地了解 Dagger1 和更多地了解 Dagger2 时,我将添加到我的答案中。这个问题更像是一个 指南 而不是一个“问题”。]
最佳答案
指南 Dagger 2.x (修订版 6):
步骤如下:
1.) 添加 Dagger
给您的 build.gradle
文件:
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.2.0'
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8' //added apt for source code generation
}
}
allprojects {
repositories {
jcenter()
}
}
apply plugin: 'com.android.application'
apply plugin: 'com.neenbedankt.android-apt' //needed for source code generation
android {
compileSdkVersion 24
buildToolsVersion "24.0.2"
defaultConfig {
applicationId "your.app.id"
minSdkVersion 14
targetSdkVersion 24
versionCode 1
versionName "1.0"
}
buildTypes {
debug {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
apt 'com.google.dagger:dagger-compiler:2.7' //needed for source code generation
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:24.2.1'
compile 'com.google.dagger:dagger:2.7' //dagger itself
provided 'org.glassfish:javax.annotation:10.0-b28' //needed to resolve compilation errors, thanks to tutplus.org for finding the dependency
}
AppContextModule
提供依赖的类。@Module //a module could also include other modules
public class AppContextModule {
private final CustomApplication application;
public AppContextModule(CustomApplication application) {
this.application = application;
}
@Provides
public CustomApplication application() {
return this.application;
}
@Provides
public Context applicationContext() {
return this.application;
}
@Provides
public LocationManager locationService(Context context) {
return (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
}
}
AppContextComponent
提供获取可注入(inject)类的接口(interface)的类。public interface AppContextComponent {
CustomApplication application(); //provision method
Context applicationContext(); //provision method
LocationManager locationManager(); //provision method
}
@Module //this is to show that you can include modules to one another
public class AnotherModule {
@Provides
@Singleton
public AnotherClass anotherClass() {
return new AnotherClassImpl();
}
}
@Module(includes=AnotherModule.class) //this is to show that you can include modules to one another
public class OtherModule {
@Provides
@Singleton
public OtherClass otherClass(AnotherClass anotherClass) {
return new OtherClassImpl(anotherClass);
}
}
public interface AnotherComponent {
AnotherClass anotherClass();
}
public interface OtherComponent extends AnotherComponent {
OtherClass otherClass();
}
@Component(modules={OtherModule.class})
@Singleton
public interface ApplicationComponent extends OtherComponent {
void inject(MainActivity mainActivity);
}
@Scope
模块的 @Singleton
上的注释(如 @ActivityScope
或 @Provides
)带注释的方法在生成的组件中获取作用域提供程序,否则它将是无作用域的,并且每次注入(inject)时都会获得一个新实例。injects={MainActivity.class}
相同):@Singleton
@Component(module={AppContextModule.class}) //this is where you would add additional modules, and a dependency if you want to subscope
public interface ApplicationComponent extends AppContextComponent { //extend to have the provision methods
void inject(MainActivity mainActivity);
}
@Module
重新定义的依赖项(例如,您使用构建风格来更改实现类型),您可以使用 @Inject
带注释的构造函数。public class Something {
OtherThing otherThing;
@Inject
public Something(OtherThing otherThing) {
this.otherThing = otherThing;
}
}
@Inject
构造函数,您可以使用字段注入(inject)而无需显式调用 component.inject(this)
:public class Something {
@Inject
OtherThing otherThing;
@Inject
public Something() {
}
}
@Inject
构造函数类会自动添加到相同作用域的组件中,而无需在模块中显式指定它们。@Singleton
范围@Inject
构造函数类将在 @Singleton
中看到作用域组件。@Singleton // scoping
public class Something {
OtherThing otherThing;
@Inject
public Something(OtherThing otherThing) {
this.otherThing = otherThing;
}
}
public interface Something {
void doSomething();
}
@Singleton
public class SomethingImpl {
@Inject
AnotherThing anotherThing;
@Inject
public SomethingImpl() {
}
}
@Module
将特定实现“绑定(bind)”到接口(interface)。 .@Module
public class SomethingModule {
@Provides
Something something(SomethingImpl something) {
return something;
}
}
@Module
public abstract class SomethingModule {
@Binds
abstract Something something(SomethingImpl something);
}
Injector
类来处理您的应用程序级组件(它取代了整体 ObjectGraph
)Rebuild Project
使用 APT 创建 DaggerApplicationComponent
构建器类)public enum Injector {
INSTANCE;
ApplicationComponent applicationComponent;
private Injector(){
}
static void initialize(CustomApplication customApplication) {
ApplicationComponent applicationComponent = DaggerApplicationComponent.builder()
.appContextModule(new AppContextModule(customApplication))
.build();
INSTANCE.applicationComponent = applicationComponent;
}
public static ApplicationComponent get() {
return INSTANCE.applicationComponent;
}
}
CustomApplication
类(class)public class CustomApplication
extends Application {
@Override
public void onCreate() {
super.onCreate();
Injector.initialize(this);
}
}
CustomApplication
给您的 AndroidManifest.xml
.<application
android:name=".CustomApplication"
...
MainActivity
中注入(inject)您的类(class)public class MainActivity
extends AppCompatActivity {
@Inject
CustomApplication customApplication;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Injector.get().inject(this);
//customApplication is injected from component
}
}
Scope
用于您可以创建的组件 Activity 级范围组件 .子作用域允许您提供仅对给定子作用域而不是在整个应用程序中需要的依赖项。通常,每个 Activity 都会通过此设置获得自己的模块。请注意存在范围内的提供者 每个组件 ,这意味着为了保留该 Activity 的实例,组件本身必须在配置更改后幸免于难。例如,它可以通过 onRetainCustomNonConfigurationInstance()
存活下来。 ,或迫击炮瞄准镜。@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface YourCustomScope {
}
ApplicationComponent
作为它的依赖。显然,您还需要在模块提供程序方法上指定子范围。@YourCustomScope
@Component(dependencies = {ApplicationComponent.class}, modules = {CustomScopeModule.class})
public interface YourCustomScopedComponent
extends ApplicationComponent {
CustomScopeClass customScopeClass();
void inject(YourScopedClass scopedClass);
}
@Module
public class CustomScopeModule {
@Provides
@YourCustomScope
public CustomScopeClass customScopeClass() {
return new CustomScopeClassImpl();
}
}
@Subcomponent
:本质上,一个范围@Subcomponent
可以替换一个组件依赖;但不是使用注释处理器提供的构建器,您需要使用组件工厂方法。@Singleton
@Component
public interface ApplicationComponent {
}
@YourCustomScope
@Component(dependencies = {ApplicationComponent.class}, modules = {CustomScopeModule.class})
public interface YourCustomScopedComponent
extends ApplicationComponent {
CustomScopeClass customScopeClass();
void inject(YourScopedClass scopedClass);
}
@Singleton
@Component
public interface ApplicationComponent {
YourCustomScopedComponent newYourCustomScopedComponent(CustomScopeModule customScopeModule);
}
@Subcomponent(modules={CustomScopeModule.class})
@YourCustomScope
public interface YourCustomScopedComponent {
CustomScopeClass customScopeClass();
}
DaggerYourCustomScopedComponent.builder()
.applicationComponent(Injector.get())
.customScopeModule(new CustomScopeModule())
.build();
Injector.INSTANCE.newYourCustomScopedComponent(new CustomScopeModule());
https://stackoverflow.com/questions/27036933/
相关文章:
android - 在 Android junit 测试用例中获取测试项目的上下文
android - 为什么一个 Android Studio 项目中有两个 build.gradle
android - 使用按钮背景颜色为我的按钮添加波纹效果?
android - Html 列表标签在 android textview 中不起作用。我能做些什么
android - 在 Android 中删除 SQLite 中的行
android - 带有 Google Maps API v2 : mysterious black
android - onActivityResult() & onResume()
android - 是否可以在 xml 描述中旋转可绘制对象?