Java 使用带有AbstractThreadedSyncAdapter的RoboGuice上下文注入

Java 使用带有AbstractThreadedSyncAdapter的RoboGuice上下文注入,java,android,inversion-of-control,guice,roboguice,Java,Android,Inversion Of Control,Guice,Roboguice,我正在使用RoboGuice 2.0b4连接我的Android应用程序,它使用了一个SyncAdapter(源自AbstractThreadedSyncAdapter),托管在一个常规服务中: @ContextSingleton public class SyncAdapter extends AbstractThreadedSyncAdapter { @Inject private AccountManager accountManager; @Inject

我正在使用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;
    }
}
不幸的是,RoboGuice在调用
作用域时变为递归时,在依赖项注入期间退出。请从
SyncAdapter
的构造函数中输入

java.lang.IllegalArgumentException: Scope for com.example.SynchronizationService@412c65b0 must be closed before scope for com.example.SynchronizationService@412c65b0 may be opened
当它看到通过
SynchronizationService
onCreate
调用附加到当前线程的上下文时。堆栈跟踪:

  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)
位于roboguice.inject.ContextScope.enter(ContextScope.java:67)
在roboguice.inject.ContextScopedRoboInjector.getInstance(ContextScopedRoboInjector.java:141)上
位于com.example.SyncAdapter.(SyncAdapter.java:65)
位于java.lang.reflect.Constructor.constructNative(Constructor.java:-1)
位于java.lang.reflect.Constructor.newInstance(Constructor.java:417)
位于com.google.inject.internal.DefaultConstructionProxyFactory$1.newInstance(DefaultConstructionProxyFactory.java:85)
位于com.google.inject.internal.ConstructorInjector.construct(ConstructorInjector.java:85)
在com.google.inject.internal.ConstructorBindingImpl$Factory.get(ConstructorBindingImpl.java:254)上
在com.google.inject.internal.ProviderToInternalFactoryAdapter$1.call(ProviderToInternalFactoryAdapter.java:46)
位于com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1031)
位于com.google.inject.internal.ProviderToInternalFactoryAdapter.get(ProviderToInternalFactoryAdapter.java:40)
位于roboguice.inject.ContextScope$1.get(ContextScope.java:126)
位于com.google.inject.internal.InternalFactoryToProviderAdapter.get(InternalFactoryToProviderAdapter.java:40)
位于com.google.inject.internal.SingleFieldInjector.inject(SingleFieldInjector.java:53)
在com.google.inject.internal.MembersInjectorImpl.injectMembers上(MembersInjectorImpl.java:110)
在com.google.inject.internal.MembersInjectorImpl$1.call(MembersInjectorImpl.java:75)上
在com.google.inject.internal.MembersInjectorImpl$1.call(MembersInjectorImpl.java:73)上
位于com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1024)
在com.google.inject.internal.MembersInjectorImpl.injectAndNotify(MembersInjectorImpl.java:73)
在com.google.inject.internal.MembersInjectorImpl.injectMembers上(MembersInjectorImpl.java:60)
位于com.google.inject.internal.InjectorImpl.injectMembers(InjectorImpl.java:944)
在roboguice.inject.ContextScopedRoboInjector.injectMembersWithoutViews(ContextScopedRoboInjector.java:243)上
在roboguice.inject.ContextScopedRoboInjector.injectMembers(ContextScopedRoboInjector.java:236)
位于roboguice.service.RoboService.onCreate(RoboService.java:57)
位于android.app.ActivityThread.handleCreateService(ActivityThread.java:2253)
[...]
位于dalvik.system.NativeStart.main(NativeStart.java:-1)
因此,显然,RoboGuice的依赖注入是不可重入的

不幸的是,SyncAdapter需要基于构造函数的注入,因为
AbstractThreadedSyncAdapter
需要向其构造函数提供上下文


有什么想法吗?我可能会攻击RoboGuice以允许重入,但这可能不是一项轻松的任务,所以我更喜欢一种侵入性较小的解决方法

看起来这实际上是RoboGuice中的一个bug。幸运的是,问题追踪器中的bug甚至附带了一个补丁: