2015-05-29 15 views
5

बस आज डैगर 2 का उपयोग करना शुरू कर दिया और मैं थोड़ा उलझन में हूं कि मुझे सबकुछ सेट करने की ज़रूरत है।एंड्रॉइड डैगर 2 पीओजेओ फील्ड इंजेक्ट नल

मैं एक पीओजेओ इंजेक्ट करने की कोशिश कर रहा हूं, लेकिन यह हमेशा शून्य है। सबसे पहले, कुछ कोड:

App.java

private AppComponent appComponent; 

@Override 
public void onCreate() { 
    super.onCreate(); 
    appComponent = DaggerAppComponent 
      .builder() 
      .appModule(new AppModule(this)) 
      .build(); 
} 

public AppComponent component() { 
    return appComponent; 
} 

AppModule.java

@Module 
public class AppModule { 
    private Application app; 

    public AppModule(Application app) { 
     this.app = app; 
    } 

    @Provides @Singleton 
    public Application application() { 
     return app; 
    } 
} 

AppComponent.java

@Singleton 
@Component(modules = AppModule.class) 
public interface AppComponent { 
    void inject(App application); 
    Application application(); 
} 

NetworkingManager.java

@Singleton 
public class NetworkingManager { 
    private Context ctx; 

    @Inject 
    public NetworkingManager(Context context) { 
     this.ctx = context; 
    } 
} 

NetModule.java

@Module 
public class NetModule { 
    @Provides @Singleton 
    public NetworkingManager provideNetworkingManager(Application application) { 
     return new NetworkingManager(application); 
    } 
} 

NetComponent.java

@Singleton 
@Component(modules = {NetModule.class}, 
     dependencies = {AppModule.class}) 
public interface NetComponent { 
    void inject(NetworkingManager networkingManager); 
} 

SomeClass.java

@Inject 
NetworkingManager networkingManager; 

public void doSomethingWithNetworkManager() { 
    networkManager.doStuff(); 
} 

मैं समय की एक अच्छा सौदा खर्च किया है ट्यूटोरियल के बहुत सारे के माध्यम से देख, अतः प्रश्न, और उदाहरण, लेकिन मैं यह समझने में सक्षम नहीं हूं कि मैं क्या गलत कर रहा हूं।

मैं 99% निश्चित हूं कि मेरे पास कुछ सेटअप गलत है, लेकिन मैं यह समझने में सक्षम नहीं हूं।

+0

ऐसा लगता है कि आपके पास थोड़ा उलझन है। आपका लक्ष्य क्या है? आप 'नेटवर्किंग प्रबंधक' का उपयोग करने की कोशिश कर रहे हैं? – Emmanuel

+0

नेटवर्कमेनर वर्तमान में एक सिंगलटन है। यह सभी async नेटवर्किंग संभालती है। यह पूरी जगह पर प्रयोग किया जाता है। मेरा लक्ष्य सिंगलटन को खत्म करना और डीआई पर स्विच करना है, साथ ही क्लास टेस्टेबल बनाना है। –

उत्तर

10

आपकी टिप्पणी के आधार पर, आप अपने आवेदन में हर जगह NetworkingManager उपलब्ध करना चाहते हैं। Component की अपनी परिभाषा के साथ

आइए शुरू:

@Singleton 
@Component(modules = AppModule.class) 
public interface AppComponent { 
    void inject(App application); 
} 

इस डैगर बताता है कि इस घटक App वर्ग इंजेक्शन दिया जाएगा। अब यहां आप डैगर अन्य कक्षाओं को भी बता सकते हैं जिन्हें आप इंजेक्ट करना चाहते हैं। तो अगर आप जोड़ना होगा अगर तुम भी उदाहरण के लिए एक Activity इंजेक्षन करना चाहते हैं:

@Singleton 
@Component(modules = AppModule.class) 
public interface AppComponent { 
    void inject(App application); 
    void inject(MainActivity activity) //Where MainActivity is a class that extends Activity. 
} 

कृपया ध्यान दें कि यह सबसे अच्छा तरीका नहीं है, IMO, आवेदन व्यापक निर्भरता साझा करने के लिए; आपको Component बनाना चाहिए जो AppComponent से प्राप्त होता है और AppComponent वांछित साझा निर्भरताओं का खुलासा करता है।

अब अपने मॉड्यूल वर्ग पर ध्यान दें:

@Module 
public class NetModule { 
    @Provides @Singleton 
    public NetworkingManager provideNetworkingManager(Application application) { 
     return new NetworkingManager(application); 
    } 
} 

यहाँ आप @Provide हैं एक NetworkingManager ing, कि ठीक है। आपके NetworkingManager को Application (Context वास्तव में) की आवश्यकता है, के अंदर App प्रदान क्यों नहीं करें?, या और भी बेहतर क्यों NetworkingManagerAppModuleAppModule के बाद से ऐसा करना चाहिए @Provide चीजें हैं जो पूरे Application के लिए आम बात है अंदर प्रदान नहीं:

@Module 
public class AppModule { 
    private Application app; 

    public AppModule(Application app) { 
     this.app = app; 
    } 

    @Provides @Singleton 
    public Application application() { 
     return app; 
    } 

    @Provides @Singleton 
    public NetworkingManager provideNetworkingManager(Application application) { 
     return new NetworkingManager(application); 
    } 
} 

अब आप अपने App वर्ग के अंदर:

public class App extends Application { 
    private AppComponent appComponent; 

@Override 
public void onCreate() { 
    super.onCreate(); 
    appComponent = DaggerAppComponent 
      .builder() 
      .appModule(new AppModule(this)) 
      .build(); 
    appComponent.inject(this); 
} 

public AppComponent component() { 
    return appComponent; 
} 
} 

और हमारे काल्पनिक MainActivity:

public class MainActivity extends Activity { 

private AppComponent appComponent; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    appComponent = ((App)getApplicationContext()).getAppComponent(); 
    appComponent.inject(this); 
    } 
} 

ऐसा लगता है कि ऐसा लगता है कि आप @Component(dependencies = {...}) सही ढंग से उपयोग नहीं कर रहे हैं। dependencies का उपयोग तब किया जाता है जब आप ऊपर वर्णित तंत्र का उपयोग करके एक Component से दूसरे पर निर्भरता का पर्दाफाश करना चाहते हैं।

+0

ठीक है, जो थोड़ा और समझ में आता है। 1) मुझे लगता है कि 'App.onCreate()' में आपका मतलब है '.build() 'और' 'इंजेक्ट (यह)', 'इंजेक्ट()' रिटर्न शून्य के रूप में। 2) 'नेटवर्किंग प्रबंधक' 'ऐप 'की तुलना में एक अलग पैकेज में है। मैं सोच रहा था कि प्रत्येक पैकेज के लिए अलग मॉड्यूल रखना बेहतर होगा। क्या यह संभव नहीं है? 3) 'MainActivity.onCreate()' में 'AppComponent' प्राप्त करना गतिविधियों और टुकड़ों के लिए ठीक है। पीओजेओ के बारे में क्या है जिनके पास एप्लिकेशन संदर्भ तक पहुंच नहीं है? क्या मुझे पहले किसी गतिविधि में संदर्भ प्राप्त करना है और इसे पीओजेओ में पास करना है? यह डैगर के साथ DI के बिंदु पर पीछे की ओर लगता है। –

+0

1) आप सही हैं, मैंने 'ऐप' कोड तय किया है। यदि आप 'ऐप' इंजेक्ट करना चाहते हैं तो आप 'इंजेक्ट()' कॉल करेंगे। 2) आप निश्चित रूप से प्रति पैकेज अलग-अलग मॉड्यूल कर सकते हैं, लेकिन मुझे लगता है कि यह प्रति स्कोप (अनुप्रयोग स्तर, गतिविधि स्तर, आदि) के विभिन्न मॉड्यूल रखने के लिए अधिक समझ में आता है। 3) पीओजेओ के लिए आप अपने कन्स्ट्रक्टर को '@ इंजेक्ट' के साथ एनोटेट कर सकते हैं अगर उन्हें किसी क्लास से इस्तेमाल किया जा रहा है जिसे पहले से ही 'घटक' द्वारा इंजेक्शन दिया गया था। यह समझने में भ्रमित हो सकता है। यदि आप चैट रूम में चाहते हैं तो हम इसके बारे में और बात कर सकते हैं। – Emmanuel

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