Служба системы закачки Roboguice

Я учусь использовать Roboguice, и у меня возникли проблемы с пониманием того, как внедрить системную службу. Все примеры, которые я видел, внедряются в действие, но я хочу внедрить его в POJO. Я использую Roboguice 2.0 бета 3

У меня есть класс PhoneNumber, и я хотел бы внедрить службу TelephonyManager.

public class PhoneNumber {
    @Inject TelephonyManager mTelephonyManager;

    protected Integer getNetworkCountryPrefix() {

        // This gives a null pointer exception 
        mTelephonyManager.getNetworkCountryIso();
    }
}

При внедрении в класс, расширяющий RoboActivity, все работает нормально. Но можно ли внедрить TelephonyManager в класс, который не расширяет RoboActivity?


person Kjetil Eide    schedule 20.12.2011    source источник


Ответы (3)


Да, есть три основных способа внедрения в ваши объекты при использовании RoboGuice.

  1. Вызовите RoboGuice.injectMembers() самостоятельно для объекта, для которого вы хотите выполнить инъекцию. Для большинства POJO это, скорее всего, будет сделано в конструкторе объекта, но может быть сделано и в другое время. Обратите внимание, что это идеальное решение, но, вероятно, наименее желательное из вариантов, поскольку оно жестко задает зависимость от вашей инфраструктуры DI (RoboGuice).

  2. Внедрите в класс, который уже делает № 1 для вас. Вы уже знакомы с этим методом... это именно то, что делает RoboActivity. По сути, большая часть того, что делает RoboActivity, — это просто вызов для вас RoboGuice.injectMembers.

  3. Внедрить TelephonyManager в класс, который сам был внедрен. Обычно это наиболее желательно, хотя в вашем конкретном случае это может быть нежелательно. Позвольте мне объяснить это ниже:

    class MyActivity extends RoboActivity {
        @Inject PhoneNumber phone;
    
        ...
    }
    
    class PhoneNumber {
        @Inject TelephonyManager tm;
    }
    

    По сути, RoboGuice просто нужен шанс выполнить инъекцию на вашем экземпляре. Для обычных POJO, которые не созданы RoboGuice, у RoboGuice нет возможности творить чудеса, если вы не вызовете injectMembers напрямую, отсюда и решение №1. Однако, если вы разрешите RoboGuice создавать экземпляр объекта для вас, например. внедрив его, RoboGuice получает контроль над созданием объекта и может сделать для вас инъекцию в этот объект. Таким образом, в приведенном выше примере, когда RoboGuice создает новый PhoneNumber и помещает его в переменную phone, RoboGuice выполнит внедрение в экземпляр, а tm будет введено правильно. Очевидно, что если вы создадите PhoneNumber с помощью оператора new() вместо того, чтобы позволить RoboGuice сделать это, у RoboGuice не будет возможности выполнить инъекцию, и tm будет нулевым.

Если № 3 работает для вас, то я бы пошел на это. Это самый гибкий способ делать что-то, и он поощряет передовой опыт, позволяя инфраструктуре DI создавать экземпляры ваших объектов для вас.

Однако, если PhoneNumber не является чем-то, что вы обычно позволяете RoboGuice создавать для вас, то вы можете рассмотреть вариант № 1.

person emmby    schedule 20.12.2011

TelephonyManager не является одной из стандартных системных служб по умолчанию, доступных для внедрения. Вам нужно будет зарегистрировать эту службу в своем модуле, прежде чем вы сможете внедрить ее в другие области.

http://code.google.com/p/roboguice/wiki/ProvidedInjections

Сделав это в своем модуле, вы можете зарегистрировать его для инъекции:

bind(TelephonyManager.class).toProvider(new SystemServiceProvider<TelephonyManager>(Context.TELEPHONY_SERVICE));
person chubbsondubs    schedule 04.04.2012

Вы можете использовать в конструкторе это

RoboGuice.getInjector(context).injectMembers(this);

просто нужен контекст

person Serhii Bohutskyi    schedule 30.08.2013