我正在学习使用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?
答案 0 :(得分:9)
是的,使用RoboGuice时,有三种主要方法可以在对象中进行注入。
自行调用RoboGuice.injectMembers()以获取要执行注入的对象。对于大多数POJO,这可能在对象的构造函数中完成,但也可以在其他时间完成。请注意,这是一个完美的解决方案,但可能是最不可取的选项,因为它硬编码了对DI框架(RoboGuice)的依赖。
注入已经为你做过#1的课程。您已熟悉此方法......这正是RoboActivity所做的。基本上,RoboActivity所做的大部分工作就是为你调用RoboGuice.injectMembers。
将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。
如果#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);
只需要上下文