Roboguice注射系统服务

时间:2011-12-20 17:14:26

标签: android dependency-injection guice roboguice

我正在学习使用Roboguice,我在理解如何注入系统服务方面遇到了麻烦。我见过的所有例子都是注入活动,但我想将它注入POJO。我正在使用Roboguice 2.0 beta 3

我有一个PhoneNumber类,想要注入TelephonyManager服务。

public class PhoneNumber {
    @Inject TelephonyManager mTelephonyManager;

    protected Integer getNetworkCountryPrefix() {

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

当注入扩展RoboActivity的类时,一切正常。但是,是否可以在不扩展RoboActivity的类中注入TelephonyManager?

3 个答案:

答案 0 :(得分:9)

是的,使用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只需要有机会在您的实例上执行注入。对于不是由RoboGuice创建的普通POJO,除非您直接调用injectMembers,否则RoboGuice没有机会发挥其魔力,因此解决方案#1。但是,如果您允许RoboGuice为您实例化对象,例如。通过注入它,RoboGuice可以控制对象的创建,并可以在该对象中为您进行注入。因此,在上面的示例中,当RoboGuice创建新的PhoneNumber并将其放入phone变量时,RoboGuice将在实例上执行注入,并且tm将被正确注入。显然,如果使用new()运算符构造PhoneNumber而不是让RoboGuice这样做,RoboGuice将没有机会执行注入,而tm将为null。

  4. 如果#3对你有用,那我就去吧。这是最灵活的做事方式,它通过让DI框架为您实例化对象来鼓励良好实践。

    但是,如果PhoneNumber不是您通常让RoboGuice为您实例化的东西,那么您可能需要考虑使用选项#1。

答案 1 :(得分:1)

TelephonyManager不是可用于注入的默认标准系统服务之一。在将模块注入其他区域之前,您必须在模块中注册该服务。

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

通过在您的模块中执行此操作,您可以将其注册为注射:

bind(TelephonyManager.class).toProvider(new SystemServiceProvider<TelephonyManager>(Context.TELEPHONY_SERVICE));

答案 2 :(得分:1)

你可以在构造函数中使用

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

只需要上下文