[英]Using RoboGuice context injection with an AbstractThreadedSyncAdapter
I am using RoboGuice 2.0b4 to wire up my Android application, which makes use of a SyncAdapter (derived from AbstractThreadedSyncAdapter) hosted in a regular service: 我正在使用RoboGuice 2.0b4连接我的Android应用程序,该应用程序使用在常规服务中托管的SyncAdapter(派生自AbstractThreadedSyncAdapter):
@ContextSingleton
public class SyncAdapter extends AbstractThreadedSyncAdapter {
@Inject
private AccountManager accountManager;
@Inject
public SyncAdapter(Context context) {
super(context, true, false);
Injector injector = RoboGuice.getInjector(context);
ContextScope scope = injector.getInstance(ContextScope.class);
synchronized(ContextScope.class) {
scope.enter(context);
try {
injector.injectMembers(this);
} finally {
scope.exit(context);
}
}
}
[...]
}
@ContextSingleton
public class SynchronizationService extends RoboService {
@Inject
private SyncAdapter syncAdapter;
@Override
public IBinder onBind(Intent intent) {
if (equal("android.content.SyncAdapter", intent.getAction())) {
return syncAdapter.getSyncAdapterBinder();
} else [...]
}
return null;
}
}
Unfortunately, RoboGuice bails out during the dependency injection when it becomes recursive while calling scope.enter
from the SyncAdapter
's constructor: 不幸的是,当从SyncAdapter
的构造函数调用scope.enter
时,RoboGuice在依赖注入期间变为递归时scope.enter
:
java.lang.IllegalArgumentException: Scope for com.example.SynchronizationService@412c65b0 must be closed before scope for com.example.SynchronizationService@412c65b0 may be opened
when it sees the context attached to the current thread by the onCreate
call of SynchronizationService
. 当它通过onCreate
调用SynchronizationService
看到附加到当前线程的上下文时。 Stack trace: 堆栈跟踪:
at roboguice.inject.ContextScope.enter(ContextScope.java:67)
at roboguice.inject.ContextScopedRoboInjector.getInstance(ContextScopedRoboInjector.java:141)
at com.example.SyncAdapter.<init>(SyncAdapter.java:65)
at java.lang.reflect.Constructor.constructNative(Constructor.java:-1)
at java.lang.reflect.Constructor.newInstance(Constructor.java:417)
at com.google.inject.internal.DefaultConstructionProxyFactory$1.newInstance(DefaultConstructionProxyFactory.java:85)
at com.google.inject.internal.ConstructorInjector.construct(ConstructorInjector.java:85)
at com.google.inject.internal.ConstructorBindingImpl$Factory.get(ConstructorBindingImpl.java:254)
at com.google.inject.internal.ProviderToInternalFactoryAdapter$1.call(ProviderToInternalFactoryAdapter.java:46)
at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1031)
at com.google.inject.internal.ProviderToInternalFactoryAdapter.get(ProviderToInternalFactoryAdapter.java:40)
at roboguice.inject.ContextScope$1.get(ContextScope.java:126)
at com.google.inject.internal.InternalFactoryToProviderAdapter.get(InternalFactoryToProviderAdapter.java:40)
at com.google.inject.internal.SingleFieldInjector.inject(SingleFieldInjector.java:53)
at com.google.inject.internal.MembersInjectorImpl.injectMembers(MembersInjectorImpl.java:110)
at com.google.inject.internal.MembersInjectorImpl$1.call(MembersInjectorImpl.java:75)
at com.google.inject.internal.MembersInjectorImpl$1.call(MembersInjectorImpl.java:73)
at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1024)
at com.google.inject.internal.MembersInjectorImpl.injectAndNotify(MembersInjectorImpl.java:73)
at com.google.inject.internal.MembersInjectorImpl.injectMembers(MembersInjectorImpl.java:60)
at com.google.inject.internal.InjectorImpl.injectMembers(InjectorImpl.java:944)
at roboguice.inject.ContextScopedRoboInjector.injectMembersWithoutViews(ContextScopedRoboInjector.java:243)
at roboguice.inject.ContextScopedRoboInjector.injectMembers(ContextScopedRoboInjector.java:236)
at roboguice.service.RoboService.onCreate(RoboService.java:57)
at android.app.ActivityThread.handleCreateService(ActivityThread.java:2253)
[...]
at dalvik.system.NativeStart.main(NativeStart.java:-1)
So, apparently, RoboGuice's dependency injection is not reentrant. 所以,显然,RoboGuice的依赖注入不是可重入的。
Unfortunately, a SyncAdapter needs constructor-based injection as AbstractThreadedSyncAdapter
expects a context to be supplied to its constructor. 不幸的是,SyncAdapter需要基于构造函数的注入,因为AbstractThreadedSyncAdapter
需要将一个上下文提供给它的构造函数。
Any ideas? 有任何想法吗? I might hack RoboGuice to allow for reentrance, but that's probably not a light undertaking, so I'd prefer a less invasive workaround. 我可能会破坏RoboGuice以允许重入,但这可能不是一项轻松的任务,所以我更喜欢一种侵入性较小的解决方法。 ;-) ;-)
Looks like this is actually a bug in RoboGuice. 看起来这实际上是RoboGuice中的一个错误。 Fortunately, the bug filed in its issue tracker even comes with a patch: http://code.google.com/p/roboguice/issues/detail?id=179 幸运的是,在其问题跟踪器中提交的错误甚至附带了一个补丁: http : //code.google.com/p/roboguice/issues/detail?id = 179
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.