2011-12-20 160 views
1

我正在学习如何使用Roboguice,而且我很难理解如何注入系统服务。我见过的所有例子都是注入一个活动,但我想将它注入POJO。我正在使用Roboguice 2.0 beta 3Roboguice注射系统服务

我有一个PhoneNumber类,并且希望注入TelephonyManager服务。

public class PhoneNumber { 
    @Inject TelephonyManager mTelephonyManager; 

    protected Integer getNetworkCountryPrefix() { 

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

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

回答

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将为空。

如果#3适合你,那么我会努力。这是最灵活的做事方式,它通过让DI框架为您实例化对象来鼓励良好实践。

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

+0

谢谢,这清理了很多。 – 2011-12-20 22:32:44

1

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

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

通过您的模块中这样做,你可以注入注册它:

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

可以在构造函数中使用这个

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

只需要上下文