2015-05-29 3 views
5

Только что начал использовать Dagger 2 сегодня, и я немного смущен тем, как именно мне нужно все настраивать.Android Dagger 2 POJO field Inject null

Я пытаюсь ввести POJO, но он всегда равен нулю. Во-первых, некоторые код:

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(); 
} 

Я потратил много времени, просматривая множество учебников, SO вопросы и примеры, но я не смог понять, что я делаю неправильно.

Я на 99% уверен, что у меня что-то не так, но я не смог понять, что.

+0

Кажется, что у вас немного замешательство. Какова ваша цель? Где вы пытаетесь использовать 'NetworkingManager'? – Emmanuel

+0

В настоящее время NetworkManager является синглом. Он обрабатывает все асинхронные сети. Он используется повсюду. Моя цель - устранить синглтон и переключиться на DI, а также сделать класс тестируемым. –

ответ

10

Основываясь на вашем комментарии, вы хотите сделать NetworkingManager доступным везде в вашем приложении. начало

Давайте с определением Component:

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

Это говорит Dagger, что этот компонент будет инъекция 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. 
} 

Пожалуйста, обратите внимание, что это не самый лучший способ, ИМО, делиться приложений широкие зависимости; вы должны создать Component, который наследует от AppComponent и делает AppComponent раскрывать нужные общие зависимости.

Теперь давайте посмотрим на ваш класс модуля:

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

Здесь вы @Provide ING в NetworkingManager, что это хорошо. Ваш NetworkingManager требует Application (a Context действительно), почему бы не указать App внутри NetworkingManager?Или даже лучше, почему бы не обеспечить NetworkingManager внутри AppModule начиная с AppModule должны @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()', а не '.inject (this)', поскольку 'inject()' возвращает void. 2) 'NetworkingManager' находится в другом пакете, чем' App'. Я думал, что было бы лучше сохранить отдельные модули для каждого пакета. Разве это невозможно? 3) Получение «AppComponent» в «MainActivity.onCreate()» отлично подходит для действий и фрагментов. Что относительно POJO, которые не имеют доступа к контексту приложения? Должен ли я сначала получить контекст в действии и передать его POJO? Это кажется обратным к точке DI с кинжалом. –

+0

1) Вы правы, я исправил код «App». Вы бы назвали 'inject()', если вы хотите также ввести 'App'. 2) У вас наверняка есть разные модули для каждого пакета, но я думаю, что имеет смысл иметь разные модули для каждой области (уровень приложения, уровень активности и т. Д.). 3) Для POJO вы можете просто аннотировать свой конструктор с помощью '@ Inject', если они используются из класса, который уже был введен с помощью« Компонента ». Это может ввести в заблуждение. Мы можем поговорить об этом, если вы хотите в чате. – Emmanuel

Смежные вопросы