Как внедрить какой-либо интерфейс в активность Android с помощью Guice

Я использую Guice 3.0 на Android, чтобы делать некоторые DI.

У меня есть

public interface APIClient { }

и

public class DefaultAPIClient implements APIClient { }

Что я сделал, так это попытался загрузить Guice в моем классе MyApplication, предоставив ему модуль, который имеет один оператор в методе настройки bind(APIClient.class).to(DefaultAPIClient.class);

Я сделал то, что сказал мне пример Guice

Injector injector = Guice.createInjector(new APIClientModule());
injector.getInstance(APIClient.class);

Возможно, я неправильно понимаю это, но как мне внедрить APIClient в несколько действий, которые будут его использовать?

Я сделал это в HomeActivity

public class HomeActivity extends RoboActivity {
    @Inject APIClient client;

    protected void onCreate(Bundle savedInstanceState) {
        client.doSomething();
    }
}

Это не работает, и это дает мне Guice configuration errors: 1) No implementation for com.mycompany.APIClient was bound

Таким образом, единственный способ заставить это работать — удалить @Inject из клиента APIClient в HomeActivity и внедрить его с помощью client = Guice.createInjector(new APIClientModule()).getInstance(APIClient.class);

Значит ли это, что мне придется делать это в каждом действии, использующем APIClient? Должно быть, я делаю что-то не так.

Любая помощь будет здорово. Спасибо!


person Adrian Rodriguez    schedule 26.11.2011    source источник


Ответы (3)


Если вы используете Roboguice 2.0 с Guice 3.0_noaop, дополнительные пользовательские модули можно определить через файл ресурсов массива строк roboguice_modules:

из документации (Обновление до 20):

Больше нет необходимости/возможности наследовать от RoboApplication, так как этого класса больше нет. Если вы хотите переопределить привязки RoboGuice по умолчанию, вы можете указать собственное имя класса модуля в ресурсе строкового массива с именем «roboguice_modules» в res/values/roboguice.xml. например.

<?xml version="1.0" encoding="utf-8"?>
<resources> 
    <string-array name="roboguice_modules">
        <item>PACKAGE.APIClientModule</item>
    </string-array>
</resources>

Поэтому вам нужно будет определить свой пользовательский модуль следующим образом:

roboguice_modules:

<?xml version="1.0" encoding="utf-8"?>
<resources> 
    <string-array name="roboguice_modules">
        <item>DONT_KNOW_YOUR_PACKAGE.APIClientModule</item>
    </string-array>
</resources>

конечно, с привязкой между APIClient и DefaultAPIClient.

и Roboguice должен сделать все остальное.

person John Ericksen    schedule 27.11.2011
comment
Я сталкивался с этим, когда проводил исследования. Есть ли способ сделать это программно, а не в XML? Я могу пойти и проследить код, но просто решил спросить, есть ли у вас быстрый ответ. Спасибо - person Adrian Rodriguez; 27.11.2011
comment
Просто невозможно настроить пользовательские модули roboguice в старой доброй Java без изменения roboguice. Вот код, который ищет определенные вами модули: code.google.com/p/roboguice/source/browse/roboguice/src/main/ строк 101+ - person John Ericksen; 27.11.2011
comment
Проверьте RoboGuice.setBaseApplicationInjector(...) для программной установки ваших модулей в версии 2.0. Вы захотите вызвать его один раз для своего приложения, чтобы вы могли использовать статический инициализатор или вызывать его из пользовательского класса приложения. code.google.com/ p/roboguice/source/browse/roboguice/src/main/ - person emmby; 27.11.2011
comment
Я исправлен, должен был немного прокрутить ;-) ... тогда вы бы определили это в переопределенном приложении или есть лучшее место для определения этого? - person John Ericksen; 27.11.2011


Вам следует использовать Guice 2.0 (без aop) вместо Guice 3.0

Чтобы правильно настроить Guice, вам нужно переопределить метод addApplicationModules(List<Module> modules) в классе вашего приложения и добавить туда свой модуль.

public class MyApplication extends RoboApplication {
  @Override
  protected void addApplicationModules(List<Module> modules) {
    modules.add(new YourModule());
  }

Чтобы использовать инъекции в своих действиях, вам нужно вызвать super.onCreate(savedInstanceState), потому что элементы внедряются в onCreate методе RoboActivity.

public class HomeActivity extends RoboActivity {
    @Inject APIClient client;

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState); // Call this before use injected members
        client.doSomething();
    }
}
person d.petrov    schedule 26.11.2011
comment
Ах. Причина, по которой я использую Guice 3.0, заключается в том, что Roboguice 1.2 теперь поддерживает Guice 3. RoboApplication устарел, и теперь ему не нужен вызов addApplicationModules. Конечно, это только в том случае, если у вас нет пользовательских модулей. В моем случае я так и сделал, поэтому я просмотрел его, и вам нужно добавить модули в roboguice.xml, но я ищу java-способ сделать это и стараюсь держаться подальше от xml, насколько это возможно. Если у вас есть идеи по добавлению пользовательских модулей в java, дайте мне знать. Спасибо. - person Adrian Rodriguez; 27.11.2011
comment
Ой, извини. Я имел в виду, что использую roboguice 2.0b3, а не 1.2. - person Adrian Rodriguez; 27.11.2011