Hướng dẫn cho Dagger 2.x (Phiên bản sửa đổi 6) :
Các bước như sau:
1.) thêm Dagger
vào build.gradle
tệp của bạn :
- cấp cao nhất 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()
}
}
- cấp ứng dụng build.gradle :
.
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
}
2.) Tạo AppContextModule
lớp của bạn cung cấp các phụ thuộc.
@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);
}
}
3.) tạo AppContextComponent
lớp cung cấp giao diện để lấy các lớp có thể đưa vào.
public interface AppContextComponent {
CustomApplication application(); //provision method
Context applicationContext(); //provision method
LocationManager locationManager(); //provision method
}
3.1.) Đây là cách bạn sẽ tạo một mô-đun với một triển khai:
@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);
}
Lưu ý:: Bạn cần cung cấp @Scope
chú thích (như @Singleton
hoặc @ActivityScope
) trên @Provides
phương thức chú thích của mô-đun để có được nhà cung cấp có phạm vi trong thành phần được tạo của bạn, nếu không nó sẽ không được mở và bạn sẽ nhận được một phiên bản mới mỗi khi bạn đưa vào.
3.2.) Tạo một thành phần có phạm vi ứng dụng chỉ định những gì bạn có thể đưa vào (điều này giống như injects={MainActivity.class}
trong Dagger 1.x):
@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);
}
3.3.) Đối với các phụ thuộc mà bạn có thể tự tạo thông qua một phương thức khởi tạo và không muốn xác định lại bằng cách sử dụng một @Module
(ví dụ: bạn sử dụng các phiên bản xây dựng để thay đổi kiểu triển khai), bạn có thể sử dụng phương thức tạo @Inject
chú thích.
public class Something {
OtherThing otherThing;
@Inject
public Something(OtherThing otherThing) {
this.otherThing = otherThing;
}
}
Ngoài ra, nếu bạn sử dụng hàm @Inject
tạo, bạn có thể sử dụng chèn trường mà không cần phải gọi rõ ràng component.inject(this)
:
public class Something {
@Inject
OtherThing otherThing;
@Inject
public Something() {
}
}
Các @Inject
lớp phương thức khởi tạo này được tự động thêm vào thành phần của cùng một phạm vi mà không cần phải chỉ định rõ ràng chúng trong một mô-đun.
Một lớp phương thức khởi tạo có @Singleton
phạm vi @Inject
sẽ được nhìn thấy trong @Singleton
các thành phần có phạm vi.
@Singleton // scoping
public class Something {
OtherThing otherThing;
@Inject
public Something(OtherThing otherThing) {
this.otherThing = otherThing;
}
}
3.4.) Sau khi bạn đã xác định một triển khai cụ thể cho một giao diện nhất định, như sau:
public interface Something {
void doSomething();
}
@Singleton
public class SomethingImpl {
@Inject
AnotherThing anotherThing;
@Inject
public SomethingImpl() {
}
}
Bạn sẽ cần "ràng buộc" việc triển khai cụ thể với giao diện bằng một @Module
.
@Module
public class SomethingModule {
@Provides
Something something(SomethingImpl something) {
return something;
}
}
Một cách ngắn gọn cho việc này kể từ Dagger 2.4 là như sau:
@Module
public abstract class SomethingModule {
@Binds
abstract Something something(SomethingImpl something);
}
4.) tạo một Injector
lớp để xử lý thành phần cấp ứng dụng của bạn (nó thay thế nguyên khối ObjectGraph
)
(lưu ý: Rebuild Project
để tạo DaggerApplicationComponent
lớp trình tạo bằng APT)
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;
}
}
5.) tạo CustomApplication
lớp học của bạn
public class CustomApplication
extends Application {
@Override
public void onCreate() {
super.onCreate();
Injector.initialize(this);
}
}
6.) thêm CustomApplication
vào của bạn AndroidManifest.xml
.
<application
android:name=".CustomApplication"
...
7.) Tiêm các lớp của bạn vàoMainActivity
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
}
}
8.) Tận hưởng!
+1.) Bạn có thể chỉ định Scope
cho các thành phần của mình mà bạn có thể tạo các thành phần có phạm vi cấp Hoạt động . Kính con cho phép bạn cung cấp các phần phụ thuộc mà bạn chỉ cần cho một kính con nhất định, thay vì trong toàn bộ ứng dụng. Thông thường, mỗi Hoạt động có mô-đun riêng với thiết lập này. Xin lưu ý rằng một nhà cung cấp có phạm vi tồn tại trên mỗi thành phần , có nghĩa là để giữ lại phiên bản cho hoạt động đó, bản thân thành phần đó phải tồn tại khi thay đổi cấu hình. Ví dụ, nó có thể tồn tại qua onRetainCustomNonConfigurationInstance()
phạm vi Mortar.
Để biết thêm thông tin về đăng ký, hãy xem hướng dẫn của Google . Ngoài ra, vui lòng xem trang web này về các phương pháp cung cấp và cả phần phụ thuộc thành phần ) và tại đây .
Để tạo phạm vi tùy chỉnh, bạn phải chỉ định chú thích bộ định mức phạm vi:
@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface YourCustomScope {
}
Để tạo một kính con, bạn cần chỉ định phạm vi trên thành phần của mình và chỉ định ApplicationComponent
là phần phụ thuộc của nó. Rõ ràng là bạn cũng cần chỉ định kính con trên các phương thức của nhà cung cấp mô-đun.
@YourCustomScope
@Component(dependencies = {ApplicationComponent.class}, modules = {CustomScopeModule.class})
public interface YourCustomScopedComponent
extends ApplicationComponent {
CustomScopeClass customScopeClass();
void inject(YourScopedClass scopedClass);
}
Và
@Module
public class CustomScopeModule {
@Provides
@YourCustomScope
public CustomScopeClass customScopeClass() {
return new CustomScopeClassImpl();
}
}
Xin lưu ý rằng chỉ một thành phần trong phạm vi có thể được chỉ định làm thành phần phụ thuộc. Hãy nghĩ về nó chính xác như cách đa kế thừa không được hỗ trợ trong Java.
+2.) Về @Subcomponent
cơ bản, một phạm vi @Subcomponent
có thể thay thế một thành phần phụ thuộc; nhưng thay vì sử dụng trình tạo do bộ xử lý chú thích cung cấp, bạn cần phải sử dụng phương pháp nhà máy thành phần.
Vì vậy, điều này:
@Singleton
@Component
public interface ApplicationComponent {
}
@YourCustomScope
@Component(dependencies = {ApplicationComponent.class}, modules = {CustomScopeModule.class})
public interface YourCustomScopedComponent
extends ApplicationComponent {
CustomScopeClass customScopeClass();
void inject(YourScopedClass scopedClass);
}
Trở thành cái này:
@Singleton
@Component
public interface ApplicationComponent {
YourCustomScopedComponent newYourCustomScopedComponent(CustomScopeModule customScopeModule);
}
@Subcomponent(modules={CustomScopeModule.class})
@YourCustomScope
public interface YourCustomScopedComponent {
CustomScopeClass customScopeClass();
}
Và điều này:
DaggerYourCustomScopedComponent.builder()
.applicationComponent(Injector.get())
.customScopeModule(new CustomScopeModule())
.build();
Trở thành cái này:
Injector.INSTANCE.newYourCustomScopedComponent(new CustomScopeModule());
+3.): Vui lòng kiểm tra các câu hỏi Stack Overflow khác liên quan đến Dagger2, chúng cung cấp rất nhiều thông tin. Ví dụ: cấu trúc Dagger2 hiện tại của tôi được chỉ định trong câu trả lời này .
Cảm ơn
Cảm ơn bạn về những hướng dẫn tại Github , TutsPlus , Joe Steele , Froger MCS và Google .
Ngoài ra đối với hướng dẫn di chuyển từng bước này, tôi đã tìm thấy sau khi viết bài đăng này.
Và để giải thích phạm vi của Kirill.
Thậm chí nhiều thông tin trong tài liệu chính thức .