Невозможно внедрить класс с помощью Dagger 2

Я пытаюсь добавить Dagger 2 в свой проект Android. Я думаю, что понимаю концепции вплоть до того момента, когда я строю график. В этот момент я стреляю в темноте, и здесь я ошибаюсь.
Все компилируется, но введенное поле пусто во время выполнения.

Я пытаюсь начать просто с внедрения Presenter в мою MainActivity. Я написал следующий код и был бы признателен за помощь в выяснении того, где я ошибся.

Мой PresenterModule.java:

@Module
public class PresenterModule {

  @Provides MainActivityPresenter providesMainActivityPresenter() {
    return new DefaultMainActivityPresenter();
  }
}

Мой класс приложения, который также включает мой компонент, следующий за кодом примера Dagger2:

public class App extends Application {

  private PresenterComponent component;

  @Singleton
  @Component(modules = PresenterModule.class)
  public interface PresenterComponent {
    void inject(App app);
    void inject(MainActivity activity);
  }


  @Override public void onCreate() {
    Log.d("App.java", "Starting Application");
    super.onCreate();

    component = DaggerApp_PresenterComponent.builder()
        .presenterModule(new PresenterModule())
        .build();
    component.inject(this);
  }

  public PresenterComponent component() {
    return component;
  }
}

И, наконец, мой MainActivity.

public class DefaultMainActivity
    extends ActionBarActivity
    implements MainActivity
{
  @Inject MainActivityPresenter mPresenter;

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

    ((App)getApplication()).component().inject(this);

    mPresenter.getCurrentDetailLineNumber();
    setContentView(R.layout.base_layout);

    getSupportActionBar();

    mContainer = (Container) findViewById(R.id.container);
    mPresenter.requestCurrentScreen();
  }

Фактический объект, который необходимо внедрить, является реализацией интерфейса, но в остальном является объектом POJO:

public class DefaultMainActivityPresenter implements MainActivityPresenter {

  private static final int SCREEN_BROWSER = 0;
  private static final int SCREEN_DETAIL = 1;

  LineNumber mCurrentDetailLineNumber;
  int mCurrentScreen;

  @Inject
  public DefaultMainActivityPresenter() {
  }
  ...
}

person MrWizard54    schedule 26.04.2015    source источник
comment
вы не говорите, в чем ошибка, время компиляции? нулевой указатель? ...   -  person Blundell    schedule 27.04.2015
comment
Извините, введенная переменная имеет значение null во время выполнения. Все нормально компилируется.   -  person MrWizard54    schedule 27.04.2015


Ответы (1)


Изменение PresenterComponent на следующее решит вашу проблему:

  @Singleton
  @Component(modules = PresenterModule.class)
  public interface PresenterComponent {
    void inject(App app);
    void inject(DefaultMainActivity activity);
  }

Это происходит из-за ковариации: хотя метод внедрения членов для типа будет принимать экземпляры его подтипов, будут вводиться только аннотированные Inject члены типа параметра и его супертипы; члены подтипов не будут. Например, для следующих типов только a и b будут внедрены в экземпляр Child, когда он будет передан методу внедрения членов injectSelf(Self instance):

   class Parent {
     @Inject A a;
   }

   class Self extends Parent {
     @Inject B b;
   }

   class Child extends Self {
     @Inject C c;
   }
person Paul Turchenko    schedule 30.04.2015
comment
Нужен ли каждому классу, которому нужна введенная переменная, вызов inject() в компоненте? - person MrWizard54; 30.04.2015
comment
К сожалению, да. Однако метод inject инициализирует все члены цепочки наследования. - person Paul Turchenko; 30.04.2015