डैगर- क्या हमें प्रत्येक गतिविधि / फ्रैगमेंट के लिए प्रत्येक घटक और मॉड्यूल बनाना चाहिए


85

मैं थोड़ी देर के लिए dagger2 के साथ काम कर रहा हूं। और मुझे प्रत्येक गतिविधि / परिहास के लिए एक घटक / मॉड्यूल बनाने के लिए भ्रमित किया गया। कृपया मुझे यह स्पष्ट करने में मदद करें:

उदाहरण के लिए, हमारे पास एक ऐप है, और ऐप में लगभग 50 स्क्रीन हैं। हम DI के लिए MVP पैटर्न और Dagger2 के बाद कोड लागू करेंगे। मान लीजिए कि हमारे पास 50 गतिविधियाँ और 50 प्रस्तुतकर्ता हैं।

मेरी राय में, आमतौर पर हमें इस तरह कोड व्यवस्थित करना चाहिए:

  1. एक AppComponent और AppModule बनाएं जो सभी ऑब्जेक्ट प्रदान करेगा जो ऐप के खुले रहने पर उपयोग किया जाएगा।

    @Module
    public class AppModule {
    
        private final MyApplicationClass application;
    
        public AppModule(MyApplicationClass application) {
            this.application = application;
        }
    
        @Provides
        @Singleton
        Context provideApplicationContext() {
            return this.application;
        }
    
        //... and many other providers 
    
    }
    
    @Singleton
    @Component( modules = { AppModule.class } )
    public interface AppComponent {
    
        Context getAppContext();
    
        Activity1Component plus(Activity1Module module);
        Activity2Component plus(Activity2Module module);
    
        //... plus 48 methods for 48 other activities. Suppose that we don't have any other Scope (like UserScope after user login, ....)
    
    }
    
  2. गतिविधि बनाएँ:

    @Scope
    @Documented
    @Retention(value=RUNTIME)
    public @interface ActivityScope {
    }
    
  3. प्रत्येक गतिविधि के लिए घटक और मॉड्यूल बनाएँ। आमतौर पर मैं उन्हें गतिविधि वर्ग के भीतर स्थिर वर्ग के रूप में रखूँगा:

    @Module
    public class Activity1Module {
    
        public LoginModule() {
        }
        @Provides
        @ActivityScope
        Activity1Presenter provideActivity1Presenter(Context context, /*...some other params*/){
            return new Activity1PresenterImpl(context, /*...some other params*/);
        }
    
    }
    
    @ActivityScope
    @Subcomponent( modules = { Activity1Module.class } )
    public interface Activity1Component {
        void inject(Activity1 activity); // inject Presenter to the Activity
    }
    
    // .... Same with 49 remaining modules and components.
    

वे सिर्फ यह दिखाने के लिए बहुत सरल उदाहरण हैं कि मैं इसे कैसे लागू करूंगा।

लेकिन मेरे एक दोस्त ने मुझे एक और कार्यान्वयन दिया:

  1. प्रस्तुतकर्ता बनाएँ जो सभी प्रस्तुतकर्ता प्रदान करेगा:

    @Module
    public class AppPresenterModule {
    
        @Provides
        Activity1Presenter provideActivity1Presentor(Context context, /*...some other params*/){
            return new Activity1PresenterImpl(context, /*...some other params*/);
        }
    
        @Provides
        Activity2Presenter provideActivity2Presentor(Context context, /*...some other params*/){
            return new Activity2PresenterImpl(context, /*...some other params*/);
        }
    
        //... same with 48 other presenters.
    
    }
    
  2. AppModule और AppComponent बनाएं:

    @Module
    public class AppModule {
    
        private final MyApplicationClass application;
    
        public AppModule(MyApplicationClass application) {
            this.application = application;
        }
    
        @Provides
        @Singleton
        Context provideApplicationContext() {
            return this.application;
        }
    
        //... and many other provides 
    
    }
    
    @Singleton
    @Component(
            modules = { AppModule.class,  AppPresenterModule.class }
    )
    public interface AppComponent {
    
        Context getAppContext();
    
        public void inject(Activity1 activity);
        public void inject(Activity2 activity);
    
        //... and 48 other methods for 48 other activities. Suppose that we don't have any other Scope (like UserScope after user login, ....)
    
    }
    

उनकी व्याख्या है: उन्हें प्रत्येक गतिविधि के लिए घटक और मॉड्यूल बनाने की आवश्यकता नहीं है। मुझे लगता है कि मेरे दोस्तों का विचार बिल्कुल अच्छा नहीं है, लेकिन अगर मैं गलत हूं तो कृपया मुझे सुधारें। ये कारण हैं:

  1. बहुत सारी मेमोरी लीक :

    • यदि उपयोगकर्ता के पास केवल 2 गतिविधियां खुली हैं, तो भी ऐप 50 प्रस्तुतकर्ता बनाएगा।
    • उपयोगकर्ता द्वारा किसी गतिविधि को बंद करने के बाद, उसका प्रस्तुतकर्ता अभी भी बना रहेगा
  2. यदि मैं एक गतिविधि के दो उदाहरण बनाना चाहता हूं तो क्या होगा? (वह दो प्रस्तुतकर्ता कैसे बना सकता है)

  3. ऐप को इनिशियलाइज़ करने में बहुत समय लगेगा (क्योंकि इसमें कई प्रेज़ेंटर्स, ऑब्जेक्ट्स, बनाने के लिए है ...)

लंबे पोस्ट के लिए क्षमा करें, लेकिन कृपया मुझे और मेरे दोस्त को यह स्पष्ट करने में मदद करें, मैं उसे मना नहीं सकता। आपकी टिप्पणियों की बहुत सराहना की जाएगी।

/ ------------------------------------------------- ---------------------- /

डेमो करने के बाद संपादित करें।

सबसे पहले, @pandawarrior उत्तर के लिए धन्यवाद। मुझे यह प्रश्न पूछने से पहले एक डेमो बनाना चाहिए था। मुझे उम्मीद है कि यहां मेरा निष्कर्ष किसी और की मदद कर सकता है।

  1. मेरे दोस्त ने जो किया है वह मेमोरी लीक का कारण नहीं बनता है जब तक कि वह किसी भी स्कोप को प्रोवाइड्स-मेथड्स में न डाले। (उदाहरण के लिए @ सिसलिंग, या @ यूसरस्कोप, ...)
  2. हम कई प्रस्तुतकर्ता बना सकते हैं, यदि प्रोवाइड-विधि में कोई स्कोप नहीं है। (तो, मेरा दूसरा बिंदु भी गलत है)
  3. डैगर प्रेजेंटर्स तभी बनाएंगे जब उनकी जरूरत होगी। (इसलिए, ऐप को इनिशियलाइज़ करने में ज़्यादा समय नहीं लगेगा, मैं लज़ीज़ इंजेक्शन से भ्रमित हो गया था)

इसलिए, ऊपर बताए गए सभी कारण ज्यादातर गलत हैं। लेकिन इसका यह मतलब नहीं है कि हमें दो कारणों से अपने मित्र विचार का पालन करना चाहिए:

  1. यह स्रोत की वास्तुकला के लिए अच्छा नहीं है, जब वह मॉड्यूल / घटक में सभी प्रस्तुतकर्ताओं को सम्मिलित करता है। (यह इंटरफ़ेस अलगाव सिद्धांत का उल्लंघन करता है , हो सकता है कि सिंगल रिस्पॉन्सिबिलिटी प्रिकेटर भी)।

  2. जब हम एक स्कोप कम्पोनेंट बनाते हैं, तो हमें पता चलेगा कि यह कब बना है और कब नष्ट हो गया है जो मेमोरी लीक से बचने के लिए बहुत बड़ा लाभ है। इसलिए, प्रत्येक गतिविधि के लिए हमें @ActivityScope के साथ एक घटक बनाना चाहिए। आइए कल्पना करें, मेरे दोस्तों के कार्यान्वयन के साथ, कि हम प्रदाता-विधि में कुछ स्कोप रखना भूल गए => मेमोरी लीक होगी।

मेरी राय में, एक छोटे से ऐप के साथ (कई निर्भरता के बिना या समान निर्भरता के साथ कुछ ही स्क्रीन), हम अपने दोस्तों के विचार को लागू कर सकते हैं, लेकिन निश्चित रूप से यह अनुशंसित नहीं है।

पर अधिक पढ़ने के लिए पसंद करते हैं: डैगर 2 में एक घटक (वस्तु ग्राफ) के जीवनचक्र को क्या निर्धारित करता है? Dagger2 गतिविधि क्षेत्र, मुझे कितने मॉड्यूल / घटकों की आवश्यकता है?

और एक और ध्यान दें: यदि आप देखना चाहते हैं कि जब वस्तु नष्ट हो जाती है, तो आप उन तरीकों को एक साथ कॉल कर सकते हैं और जीसी तुरंत चलेगा:

    System.runFinalization();
    System.gc();

यदि आप इन विधियों में से केवल एक का उपयोग करते हैं, तो जीसी बाद में चलेगा, और आपको गलत परिणाम मिल सकते हैं।

जवाबों:


85

प्रत्येक के लिए एक अलग मॉड्यूल की घोषणा करना Activityएक अच्छा विचार नहीं है। प्रत्येक के लिए अलग घटक की घोषणा Activityकरना और भी बुरा है। इसके पीछे तर्क बहुत सरल है - आपको वास्तव में इन सभी मॉड्यूल / घटकों की आवश्यकता नहीं है (जैसा कि आप पहले से ही खुद देख चुके हैं)।

हालाँकि, केवल एक घटक है जो Applicationजीवन-चक्र से जुड़ा हुआ है और सभी में इंजेक्शन के लिए इसका उपयोग करना Activitiesभी इष्टतम समाधान नहीं है (यह आपके मित्र का दृष्टिकोण है)। यह इष्टतम नहीं है क्योंकि:

  1. यह आपको केवल एक दायरे ( @Singletonया एक कस्टम) के लिए प्रतिबंधित करता है
  2. इंजेक्ट की गई वस्तुओं को "एप्लिकेशन एकल" बनाने के लिए केवल वही स्कोप सीमित है, इसलिए स्कोप की गई वस्तुओं के गलत या गलत उपयोग में गलती से वैश्विक मेमोरी लीक हो सकती है
  3. आप Servicesभी इंजेक्षन करने के लिए Dagger2 का उपयोग करना चाहते हैं, लेकिन Servicesइसके लिए विभिन्न वस्तुओं की आवश्यकता हो सकती है Activities(उदाहरण के Servicesलिए प्रस्तुतकर्ता की आवश्यकता नहीं है FragmentManager, आदि)। एकल घटक का उपयोग करके आप विभिन्न घटकों के लिए अलग-अलग ऑब्जेक्ट ग्राफ़ को परिभाषित करने के लचीलेपन को ढीला करते हैं।

तो, प्रति घटक Activityएक ओवरकिल है, लेकिन पूरे आवेदन के लिए एकल घटक पर्याप्त लचीला नहीं है। इन चरम सीमाओं के बीच इष्टतम समाधान होता है (जैसा कि आमतौर पर होता है)।

मैं निम्नलिखित दृष्टिकोण का उपयोग करता हूं:

  1. एकल "एप्लिकेशन" घटक जो "वैश्विक" ऑब्जेक्ट प्रदान करता है (उदाहरण के लिए वैश्विक स्थिति रखने वाली वस्तुएं जो एप्लिकेशन में सभी घटकों के बीच साझा की जाती हैं)। में झटपट तैयार किया Application
  2. "नियंत्रक" उप-अनुप्रयोग "घटक" घटक है जो उन वस्तुओं को प्रदान करता है जो सभी उपयोगकर्ता-सामना करने वाले "नियंत्रकों" (मेरी वास्तुकला में ये हैं Activitiesऔर Fragments) द्वारा आवश्यक हैं । प्रत्येक में त्वरित Activityऔर Fragment
  3. "सेवा" "अनुप्रयोग" घटक का उपसंपादक जो सभी को आवश्यक वस्तुओं को प्रदान करता है Services। प्रत्येक में त्वरित Service

निम्नलिखित एक उदाहरण है कि आप उसी दृष्टिकोण को कैसे लागू कर सकते हैं।


जुलाई 2017 को संपादित करें

मैंने एक वीडियो ट्यूटोरियल प्रकाशित किया जिसमें दिखाया गया है कि एंड्रॉइड एप्लिकेशन में डैगर निर्भरता इंजेक्शन कोड को कैसे तैयार किया जाए: पेशेवर ट्यूटोरियल के लिए एंड्रॉइड डैगर


फरवरी 2018 को संपादित करें

मैंने एंड्रॉइड में निर्भरता इंजेक्शन के बारे में एक पूरा पाठ्यक्रम प्रकाशित किया ।

इस कोर्स में मैं निर्भरता इंजेक्शन के सिद्धांत की व्याख्या करता हूं और दिखाता हूं कि यह एंड्रॉइड एप्लिकेशन में स्वाभाविक रूप से कैसे उभरता है। तब मैं प्रदर्शित करता हूं कि डैगर सामान्य निर्भरता इंजेक्शन योजना में कैसे फिट होते हैं।

यदि आप इस पाठ्यक्रम को लेते हैं, तो आप समझेंगे कि प्रत्येक गतिविधि / विखंडन के लिए मॉड्यूल / घटक की एक अलग परिभाषा होने का विचार मूल रूप से सबसे मौलिक तरीके से क्यों दोषपूर्ण है।

इस तरह के दृष्टिकोण से कक्षाओं के "निर्माण" सेट में संरचना के "कार्यात्मक" सेट से प्रस्तुति परत की संरचना होती है, इस प्रकार उन्हें एक साथ युग्मित किया जाता है। यह निर्भरता इंजेक्शन के मुख्य उद्देश्य के खिलाफ जाता है जो कक्षाओं के "कंस्ट्रक्शन" और "कार्यात्मक" सेटों को अलग रखना है।


आवेदन गुंजाइश:

@ApplicationScope
@Component(modules = ApplicationModule.class)
public interface ApplicationComponent {

    // Each subcomponent can depend on more than one module
    ControllerComponent newControllerComponent(ControllerModule module);
    ServiceComponent newServiceComponent(ServiceModule module);

}


@Module
public class ApplicationModule {

    private final Application mApplication;

    public ApplicationModule(Application application) {
        mApplication = application;
    }

    @Provides
    @ApplicationScope
    Application applicationContext() {
        return mApplication;
    }

    @Provides
    @ApplicationScope
    SharedPreferences sharedPreferences() {
        return mApplication.getSharedPreferences(Constants.PREFERENCES_FILE, Context.MODE_PRIVATE);
    }

    @Provides
    @ApplicationScope
    SettingsManager settingsManager(SharedPreferences sharedPreferences) {
        return new SettingsManager(sharedPreferences);
    }
}

नियंत्रक गुंजाइश:

@ControllerScope
@Subcomponent(modules = {ControllerModule.class})
public interface ControllerComponent {

    void inject(CustomActivity customActivity); // add more activities if needed

    void inject(CustomFragment customFragment); // add more fragments if needed

    void inject(CustomDialogFragment customDialogFragment); // add more dialogs if needed

}



@Module
public class ControllerModule {

    private Activity mActivity;
    private FragmentManager mFragmentManager;

    public ControllerModule(Activity activity, FragmentManager fragmentManager) {
        mActivity = activity;
        mFragmentManager = fragmentManager;
    }

    @Provides
    @ControllerScope
    Context context() {
        return mActivity;
    }

    @Provides
    @ControllerScope
    Activity activity() {
        return mActivity;
    }

    @Provides
    @ControllerScope
    DialogsManager dialogsManager(FragmentManager fragmentManager) {
        return new DialogsManager(fragmentManager);
    }

    // @Provides for presenters can be declared here, or in a standalone PresentersModule (which is better)
}

और फिर में Activity:

public class CustomActivity extends AppCompatActivity {

    @Inject DialogsManager mDialogsManager;

    private ControllerComponent mControllerComponent;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getControllerComponent().inject(this);

    }

    private ControllerComponent getControllerComponent() {
        if (mControllerComponent == null) {

            mControllerComponent = ((MyApplication)getApplication()).getApplicationComponent()
                    .newControllerComponent(new ControllerModule(this, getSupportFragmentManager()));
        }

        return mControllerComponent;
    }
}

निर्भरता इंजेक्शन पर अतिरिक्त जानकारी:

डैगर 2 स्कोप्स डिमिस्टिफाई

Android में निर्भरता इंजेक्शन


1
अपनी राय साझा करने के लिए धन्यवाद @vasiliy यह वास्तव में है कि मैं इसका उपयोग कैसे करूंगा और वर्तमान में रणनीति का पालन करूंगा। एमवीपी पैटर्न के मामले में, संदर्भित ControllerModuleएक नया निर्माण करेगा Presenterऔर फिर प्रस्तुतकर्ता को Activityया में इंजेक्ट किया जाएगा Fragment। इसके पक्ष में या इसके खिलाफ कोई ठोस राय?
वाहिब उल हक

@Vasiliy, मैंने आपका पूरा लेख पढ़ा और मैंने पाया कि हो सकता है कि आपने तंत्र में इंटरेक्टर्स और प्रेजेंटर्स पर विचार नहीं किया हो । क्या कंट्रोलरमॉड्यूल इंटरेक्टर्स और प्रेजेंटर्स की सभी निर्भरता प्रदान करेगा ? यदि मुझे कुछ भी याद है तो कृपया एक छोटा संकेत दें।
आईएमसी क्रिप्टोकरंसी

@ mahbub.kuet, अगर मुझे समझ में आ रहा है कि आप "इंटरेक्टर्स" और "प्रेजेंटर्स" का क्या जिक्र कर रहे हैं, तो ControllerComponentउन्हें इंजेक्ट करना चाहिए। चाहे आप उन्हें अंदर से तार करते हैं ControllerModule, या अतिरिक्त मॉड्यूल शुरू करते हैं , आप पर निर्भर है। वास्तविक एप्लिकेशन में मैं एक मॉड्यूल में सब कुछ डालने के बजाय प्रति घटक दृष्टिकोण के मल्टी-मॉड्यूल का उपयोग करने की सलाह देता हूं। यहाँ के लिए एक उदाहरण है ApplicationComponent, लेकिन नियंत्रक समान होगा: github.com/techyourchance/idocare-android/tree/master/app/src/…
Vasiliy

2
@ श्रीमान, सामान्य रूप से हाँ, लेकिन फिर आपको स्पष्ट रूप से ApplicationComponentउन सभी निर्भरताओं की घोषणा करनी होगी जो ControllerComponentउपयोग कर सकते हैं। साथ ही उत्पन्न कोड की विधि संख्या अधिक होगी। मुझे अभी तक निर्भर घटकों का उपयोग करने का एक अच्छा कारण नहीं मिला है।
वासिलि

1
मैं आज अपनी सभी परियोजनाओं में इस दृष्टिकोण का उपयोग कर रहा हूं और मैं स्पष्ट रूप से dagger.androidपैकेज से किसी भी चीज का उपयोग नहीं करता हूं क्योंकि मुझे लगता है कि यह बीमार है। इसलिए, यह उदाहरण अभी भी बहुत पुराना है और अभी भी Android IMHO में DI करने का सबसे अच्छा तरीका है।
वासिलि

15

अपने घटकों, मॉड्यूलों और पैकेजों को कैसे व्यवस्थित करें, इसके कुछ सर्वोत्तम उदाहरण यहां Google Android आर्किटेक्चर ब्लूप्रिंट्स Github रेपो में देखे जा सकते हैं

यदि आप वहां स्रोत कोड की जांच करते हैं, तो आप देख सकते हैं कि एक एकल ऐप-स्कोप्ड कंपोनेंट है (संपूर्ण ऐप की अवधि के एक जीवनचक्र के साथ) और फिर एक्टिविटी और फ्रॉगमेंट के लिए अलग-अलग एक्टिविटी-स्कॉप्ड कंपोनेंट्स दिए गए हैं, परियोजना। उदाहरण के लिए, निम्नलिखित पैकेज हैं:

addedittask
taskdetail
tasks

प्रत्येक पैकेज के अंदर एक मॉड्यूल, घटक, प्रस्तुतकर्ता आदि होता है। उदाहरण के लिए, अंदर taskdetailनिम्न वर्ग हैं:

TaskDetailActivity.java
TaskDetailComponent.java
TaskDetailContract.java
TaskDetailFragment.java
TaskDetailPresenter.java
TaskDetailPresenterModule.java

इस तरह से आयोजित करने का लाभ (एक घटक या मॉड्यूल में सभी गतिविधियों को समूहीकृत करने के बजाय) यह है कि आप जावा एक्सेसिबिलिटी संशोधक का लाभ उठा सकते हैं और प्रभावी जावा आइटम को पूरा कर सकते हैं 13. दूसरे शब्दों में, कार्यात्मक रूप से समूहीकृत कक्षाएं समान में होंगी। पैकेज और आप अपनी कक्षाओं के अनपेक्षित usages को रोकने के लिए protectedऔर package-private पहुँच संशोधक का लाभ ले सकते हैं ।


1
यह मेरा पसंदीदा तरीका भी है। मैं उन गतिविधियों / अंशों को पसंद नहीं करता, जिनके लिए वे नहीं चाहते हैं।
जोआओ सोसा

3

पहला विकल्प प्रत्येक गतिविधि के लिए एक उप-स्तरित घटक बनाता है, जहाँ गतिविधि उप-घटक घटक बनाने में सक्षम होती है जो केवल उस विशेष गतिविधि के लिए निर्भरता (प्रस्तुतकर्ता) प्रदान करते हैं।

दूसरा विकल्प एक एकल @Singletonघटक बनाता है जो प्रस्तुतकर्ताओं को बिना किसी निर्भरता के प्रदान करने में सक्षम है, जिसका अर्थ है जब आप उन्हें एक्सेस करते हैं, तो आप प्रत्येक बार प्रस्तुतकर्ता का एक नया उदाहरण बनाते हैं। (नहीं, यह एक नया उदाहरण नहीं बनाता है जब तक आप एक अनुरोध नहीं करते हैं)।


तकनीकी रूप से, न तो दृष्टिकोण दूसरे से भी बदतर है। पहला दृष्टिकोण प्रस्तुतकर्ताओं को सुविधा द्वारा अलग नहीं करता है, लेकिन परत द्वारा।

मैंने दोनों का उपयोग किया है, वे दोनों काम करते हैं और दोनों समझ में आते हैं।

पहले समाधान का एकमात्र नुकसान (यदि आप @Component(dependencies={...}इसके बजाय उपयोग कर रहे हैं @Subcomponent) यह है कि आपको यह सुनिश्चित करने की आवश्यकता है कि यह गतिविधि नहीं है जो आंतरिक रूप से अपना स्वयं का मॉड्यूल बनाता है, क्योंकि तब आप मॉड्यूल विधि कार्यान्वयन को मोक्स से बदल नहीं सकते हैं। फिर से, यदि आप फ़ील्ड इंजेक्शन के बजाय कंस्ट्रक्टर इंजेक्शन का उपयोग करते हैं, तो आप सीधे निर्माता के साथ सीधे वर्ग बना सकते हैं, सीधे इसे मॉक दे सकते हैं।


1

Provider<"your component's name">मेमोरी लीक से बचने और बेकार घटकों के टन बनाने के लिए सरल घटकों के कार्यान्वयन के बजाय उपयोग करें । इसलिए जब आप कॉल करते हैं तो आपके घटक आलसी द्वारा बनाए जाते हैं (क्योंकि विधि) क्योंकि आप घटक का उदाहरण नहीं देते हैं, लेकिन इसके बजाय सिर्फ प्रदाता। इस प्रकार आपके प्रस्तोता को लागू किया जाता है यदि .get () प्रदाता का कहा जाता है। प्रदाता के बारे में यहां पढ़ें और इसे लागू करें। ( आधिकारिक खंजर प्रलेखन )


और अन्य बढ़िया तरीका है मल्टीबाइंडिंग का उपयोग करना। इसके अनुसार आपको अपने प्रस्तुतकर्ताओं को मानचित्र में बाँधना चाहिए और ज़रूरत पड़ने पर उन्हें प्रदाताओं के माध्यम से बनाना चाहिए। ( यहाँ मल्टीबाइंडिंग के बारे में डॉक्स है )


-5

आपका दोस्त सही है, आपको वास्तव में हर गतिविधियों के लिए घटक और मॉड्यूल नहीं बनाने हैं। डैगर आपको गंदे कोड को कम करने में मदद करने के लिए माना जाता है और आपकी एंड्रॉइड गतिविधियों को क्लास के इंस्टिट्यूशन को मॉड्यूल्स के रूप में प्रस्तुत करने के बजाय उन्हें गतिविधियों के ऑनक्रिट विधि में इंस्टेंटिएट करता है।

आम तौर पर हम ऐसा करेंगे

public class MainActivity extends AppCompatActivity {


Presenter1 mPresenter1;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    mPresenter1 = new Presenter1(); // you instantiate mPresentation1 in onCreate, imagine if there are 5, 10, 20... of objects for you to instantiate.
}

}

आप इसके बजाय ऐसा करें

public class MainActivity extends AppCompatActivity {

@Inject
Presenter1 mPresenter1; // the Dagger module take cares of instantiation for your

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

private void injectThisActivity() {
    MainApplication.get(this)
            .getMainComponent()
            .inject(this);
}}

तो बहुत सी चीजें लिखना हार के उद्देश्य की तरह नहीं? अगर मैं हर गतिविधियों के लिए मॉड्यूल और घटक बनाने के लिए है, तो मैं गतिविधियों में अपने प्रस्तुतकर्ताओं को तुरंत समाप्त करता हूं।

आपके प्रश्नों के बारे में:

1- मेमोरी लीक:

नहीं, जब तक आप प्रस्तुतकर्ताओं को एक @Singletonएनोटेशन नहीं देते हैं। जब भी आप @Injectलक्ष्य वर्ग में करते हैं, तो डैगर केवल ऑब्जेक्ट का निर्माण करेगा । यह आपके परिदृश्य में अन्य प्रस्तुतकर्ता नहीं बनाएगा। आप लॉग बनाने के लिए यह देखने की कोशिश कर सकते हैं कि वे बनाए गए हैं या नहीं।

@Module
public class AppPresenterModule {

@Provides
@Singleton // <-- this will persists throughout the application, too many of these is not good
Activity1Presenter provideActivity1Presentor(Context context, ...some other params){
    Log.d("Activity1Presenter", "Activity1Presenter initiated");
    return new Activity1PresenterImpl(context, ...some other params);
}

@Provides // Activity2Presenter will be provided every time you @Inject into the activity
Activity2Presenter provideActivity2Presentor(Context context, ...some other params){
    Log.d("Activity2Presenter", "Activity2Presenter initiated");
    return new Activity2PresenterImpl(context, ...some other params);
}

.... Same with 48 others presenters.

}

2- आप दो बार इंजेक्ट करें और उनका हैश कोड लॉग करें

//MainActivity.java
@Inject Activity1Presenter mPresentation1
@Inject Activity1Presenter mPresentation2

@Inject Activity2Presenter mPresentation3
@Inject Activity2Presenter mPresentation4
//log will show Presentation2 being initiated twice

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    injectThisActivity();
    Log.d("Activity1Presenter1", mPresentation1.hashCode());
    Log.d("Activity1Presenter2", mPresentation2.hashCode());
    //it will shows that both have same hash, it's a Singleton
    Log.d("Activity2Presenter1", mPresentation3.hashCode());
    Log.d("Activity2Presenter2", mPresentation4.hashCode());
    //it will shows that both have different hash, hence different objects

3. नहीं, ऑब्जेक्ट केवल तब बनाए जाएंगे जब आप @Injectऐप इनिट के बजाय गतिविधियों में शामिल होंगे।


1
टिप्पणी के लिए धन्यवाद, आपने जो कहा है वह गलत नहीं है, लेकिन मुझे लगता है कि यह सबसे अच्छा जवाब नहीं है, कृपया मेरी संपादित पोस्ट देखें। इसलिए, इसे स्वीकार नहीं किया जा सका।
श्री माइक

@EpicPandaForce: एह, लेकिन आपको इसे कहीं और तुरंत भेजना होगा। कुछ निर्भरता उलटा सिद्धांत का उल्लंघन करना होगा।
डेविड लियू
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.