2014-10-23 7 views
5

मेरे पास एक मोर्टार एप्लिकेशन है, जिसमें मोर्टारएक्टिविटीस्कोप रूट स्कोप के तहत पहले बच्चे के रूप में है।मॉर्टारएक्टिविटीस्कोप के लिए गतिविधि को प्रावधान कैसे करें, अभिविन्यास परिवर्तनों पर गतिविधि को लीक किए बिना?

@Module(addsTo = ApplicationModule.class, injects = {Foo.class, SomePresenter.class, AnotherPresenter.class}) 
public class ActivityModule { 

    private final Activity activity; 

    public ActivityModule(Activity activity) { 
     this.activity = activity; 
    } 

    @Provides Activity provideActivity() { 
     return activity; 
    } 
} 

public class Foo { 
    private final Activity activity; 
    @Inject(Activity activity) { 
     this.activity = activity; 
    } 
    public void doSomethingWithActivity() { 
     // do stuff with activity: findViewById(), getWindow(), mess with action bar etc. 
    } 
} 

यह जब तक एक ओरिएंटेशन परिवर्तन होता है ठीक है: MortarActivityScope एक ActivityScope जो इंजेक्शन कक्षाओं के लिए एक गतिविधि @Provides है। मोर्टार नमूना प्रोजेक्ट में, गतिविधि स्कोप अभिविन्यास परिवर्तनों पर नष्ट नहीं होता है। यह संभवतः अभिविन्यास परिवर्तनों में बने रहने के लिए @ सिंगलेटन प्रस्तुतियों, स्क्रीन इत्यादि को अनुमति देने के लिए है। आप नमूना परियोजना की मुख्य गतिविधि में OnDestroy() विधि में देख सकते हैं:

@Override protected void onDestroy() { 
    super.onDestroy(); 

    actionBarOwner.dropView(this); 

    // activityScope may be null in case isWrongInstance() returned true in onCreate() 
    if (isFinishing() && activityScope != null) { 
     MortarScope parentScope = Mortar.getScope(getApplication()); 
     parentScope.destroyChild(activityScope); 
     activityScope = null; 
    } 
    } 
} 

हालांकि, यह कर रही है इस तरह से इसका मतलब है कि वर्ष ObjectGraph उन्मुखीकरण परिवर्तन भर में बनी हुई है। मैंने देखा है कि Mortar.requireActivityScope नए ब्लूप्रिंट द्वारा प्रदान किए गए नए मॉड्यूल के साथ पुराने गतिविधि क्षेत्र से मॉड्यूल को प्रतिस्थापित नहीं करता है। इसके बजाए, ऑब्जेक्ट ग्राफ़ नष्ट मॉड्यूल सहित पिछले मॉड्यूल के संदर्भ को बरकरार रखता है।

public class MyActivity extends Activity implements Blueprint { 

    @Inject foo; 

    @Override protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     MortarScope parentScope = Mortar.getScope(getApplication()); 
     activityScope = Mortar.requireActivityScope(parentScope, this); 
     Mortar.inject(this, this); 

     foo.doSomethingWithActivity(); //fails, because activity injected by object graph is destroyed 
    } 

    @Override 
    public String getMortarScopeName() { 
     return getClass().getName(); 
    } 

    @Override 
    public Object getDaggerModule() { 
     return new ActivityModule(this); 
    } 
} 

मोर्टार नमूना गतिविधि मुख्य मॉड्यूल में एक @Provides Activity विधि सहित नहीं द्वारा इस के आसपास पाने के लिए लगता है। लेकिन MortarActivityScope गतिविधि को इंजेक्ट करने में सक्षम नहीं होना चाहिए? अभिविन्यास परिवर्तन पर आपके सभी सिंगलटन ऑब्जेक्ट्स (Presenter ऑब्जेक्ट्स इत्यादि) खोने के बिना ऐसा करने का पसंदीदा तरीका क्या है?

उत्तर

5

किसी को गतिविधि को इंजेक्ट करने की अनुमति न दें, जिसे सुरक्षित नहीं किया जा सकता है। इसके बजाय एक प्रस्तुतकर्ता इंजेक्ट करें जो गतिविधि से जुड़ा हुआ है।

How to handle onActivityResult() with Mortar में एक प्रेजेंटर के स्वामित्व वाली गतिविधि का एक उदाहरण शामिल है। अन्य प्रस्तुतियों समेत आपके ऐप के अन्य हिस्सों, फिर उसे इंजेक्ट कर सकते हैं और ऐसा करने के लिए कह सकते हैं कि उन्हें जो कुछ भी करने की ज़रूरत है, उसे गतिविधि से निपटने की आवश्यकता है।

और सभी गतिविधि-विशिष्ट कार्य को एक गतिविधि प्रस्तुति में जोड़ने की आवश्यकता नहीं है। हमारी गतिविधि में कई प्रस्तुतियां हैं जो शेष सेवाओं के लिए अपनी सेवाएं ब्रोकर करती हैं।

+0

बहुत ही सुरुचिपूर्ण। इंजेक्शन प्रेजेंटर का उपयोग करना एक ऐसा मार्ग है जिसे मैंने कभी नहीं सोचा था, और गतिविधि के संदर्भ में हर ऑब्जेक्ट को मैन्युअल रूप से अपडेट करने से बहुत कम बहीखाता है। – weefbellington

संबंधित मुद्दे