डैगर 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
}
2.) अपनी 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);
}
}
3.) वह AppContextComponent
वर्ग बनाएं जो इंटरफ़ेस को उन वर्गों को प्राप्त करने के लिए प्रदान करता है जो इंजेक्शन योग्य हैं।
public interface AppContextComponent {
CustomApplication application(); //provision method
Context applicationContext(); //provision method
LocationManager locationManager(); //provision method
}
3.1।) यह है कि आप एक कार्यान्वयन के साथ एक मॉड्यूल कैसे बनाएंगे:
@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
, अन्यथा यह अनियंत्रित हो जाएगा, और आपको हर बार इंजेक्शन लगाने पर एक नया उदाहरण मिलेगा।
3.2।) एक एप्लिकेशन-स्कॉप्ड घटक बनाएं जो निर्दिष्ट करता है कि आप क्या इंजेक्ट कर सकते हैं (यह 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);
}
3.3।) निर्भरता के लिए जिसे आप स्वयं एक कंस्ट्रक्टर के माध्यम से बना सकते हैं और @Module
(उदाहरण के लिए, आप कार्यान्वयन के प्रकार को बदलने के बजाय बिल्ड फ़्लेवर का उपयोग करते हैं) का उपयोग करके उसे फिर से परिभाषित नहीं करना चाहेंगे , आप @Inject
एनोटेट किए गए कंस्ट्रक्टर का उपयोग कर सकते हैं ।
public class Something {
OtherThing otherThing;
@Inject
public Something(OtherThing otherThing) {
this.otherThing = otherThing;
}
}
इसके अलावा, यदि आप @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;
}
}
3.4।) के बाद आप किसी दिए गए इंटरफ़ेस के लिए एक विशिष्ट कार्यान्वयन को परिभाषित करते हैं, जैसे:
public interface Something {
void doSomething();
}
@Singleton
public class SomethingImpl {
@Inject
AnotherThing anotherThing;
@Inject
public SomethingImpl() {
}
}
आपको इंटरफ़ेस के साथ विशिष्ट कार्यान्वयन को "बाइंड" करना होगा @Module
।
@Module
public class SomethingModule {
@Provides
Something something(SomethingImpl something) {
return something;
}
}
इस के लिए एक छोटा हाथ के बाद से Dagger 2.4 निम्नलिखित है:
@Module
public abstract class SomethingModule {
@Binds
abstract Something something(SomethingImpl something);
}
4.)Injector
अपने एप्लिकेशन-स्तरीय घटक को संभालने के लिए एक वर्ग बनाएं (यह अखंड को बदल देता है ObjectGraph
)
(नोट: एपीटी का उपयोग करके बिल्डर वर्ग Rebuild Project
बनाने के लिए 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;
}
}
5.) अपनी CustomApplication
कक्षा बनाएं
public class CustomApplication
extends Application {
@Override
public void onCreate() {
super.onCreate();
Injector.initialize(this);
}
}
6.)CustomApplication
अपने में जोड़ें AndroidManifest.xml
।
<application
android:name=".CustomApplication"
...
7.) अपनी कक्षाओं को इंजेक्ट करेंMainActivity
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.) आनंद लें!
+1।) आप Scope
अपने घटकों के लिए निर्दिष्ट कर सकते हैं जिसके साथ आप गतिविधि-स्तर के स्कॉप किए गए घटक बना सकते हैं । सब्कोकॉप्स आपको उन निर्भरताएँ प्रदान करने की अनुमति देता है, जिनकी आपको केवल पूरे आवेदन के बजाय किसी दिए गए उप-कोड के लिए ही आवश्यकता होती है। आमतौर पर, प्रत्येक गतिविधि को इस सेटअप के साथ अपना स्वयं का मॉड्यूल मिलता है। कृपया ध्यान दें कि एक स्कॉप्ड प्रदाता प्रति घटक मौजूद है , जिसका अर्थ है कि गतिविधि के लिए उदाहरण को बनाए रखने के लिए, घटक को कॉन्फ़िगरेशन परिवर्तन से बचना होगा। उदाहरण के लिए, यह onRetainCustomNonConfigurationInstance()
एक मोर्टार गुंजाइश के माध्यम से जीवित रह सकता है।
सदस्यता के बारे में अधिक जानकारी के लिए, Google द्वारा मार्गदर्शिका देखें । कृपया इस साइट को प्रावधान विधियों और घटक निर्भरता अनुभाग ) और यहाँ के बारे में भी देखें ।
कस्टम स्कोप बनाने के लिए, आपको स्कोप क्वालिफायर एनोटेशन निर्दिष्ट करना होगा:
@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();
}
}
कृपया ध्यान दें कि केवल एक स्कॉप्ड घटक को एक निर्भरता के रूप में निर्दिष्ट किया जा सकता है। इसे ठीक उसी तरह से सोचें जैसे जावा में मल्टीपल इनहेरिटेंस का समर्थन नहीं किया गया है।
+2।) के बारे में @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());
+3।): कृपया Dagger2 के बारे में अन्य स्टैक ओवरफ्लो प्रश्नों की जांच करें, वे बहुत सारी जानकारी प्रदान करते हैं। उदाहरण के लिए, इस उत्तर में मेरी वर्तमान Dagger2 संरचना निर्दिष्ट है ।
धन्यवाद
Github , TutsPlus , Joe Steele , Froger MCS और Google के मार्गदर्शकों के लिए धन्यवाद ।
इसके अलावा इस कदम से कदम प्रवास गाइड मैं इस पोस्ट लिखने के बाद मिला।
और किरिल द्वारा गुंजाइश की व्याख्या के लिए ।
आधिकारिक दस्तावेज में और भी अधिक जानकारी ।