Guice Extension - Assisted Inject の助けを借りて、RoboGuice 2.0 を使用して Android プロジェクトを作成しています。現在、非 UI スレッドでファクトリを介してコンテキストを注入する際に問題に直面しています。
私の問題を示すサンプルプロジェクト:
個人インターフェース:
public interface Person {
}
人の実装:
@AssistedInject
public PersonImpl(@Assisted String name, @Assisted int age, Context context) {
}
@Inject
public PersonImpl(Context context) {
}
パーフォン工場:
Person create(@Assisted String name, @Assisted int age);
モジュール:
private static class TestModule extends AbstractModule {
@Override
protected void configure() {
bind(Person.class).to(PersonImpl.class);
install(new FactoryModuleBuilder()
.implement(Person.class, PersonImpl.class)
.build(PersonFactory.class));
}
}
主な活動:
@Inject
private PersonFactory personFactory;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
Person p = RoboGuice.getInjector(MainActivity.this).getInstance(Person.class);
Log.d("TAG", "By injector " + p.toString());
p = personFactory.create("AAA", 123);
Log.d("TAG", "By factory " + p.toString());
return null;
}
}.execute();
}
AsyncTask が実行されるとインジェクターが Person オブジェクトを作成します。この操作は正常に機能し、期待どおりに PersonImpl オブジェクトが返されます。ただし、ファクトリが新しい Person オブジェクトを作成しようとすると、次の例外が発生します。
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:300)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:841)
Caused by: java.util.EmptyStackException
at java.util.Stack.peek(Stack.java:57)
at roboguice.inject.ContextScope$1.get(ContextScope.java:108)
at com.google.inject.internal.InternalFactoryToProviderAdapter.get(InternalFactoryToProviderAdapter.java:41)
at com.google.inject.internal.SingleParameterInjector.inject(SingleParameterInjector.java:38)
at com.google.inject.internal.SingleParameterInjector.getAll(SingleParameterInjector.java:62)
at com.google.inject.internal.ConstructorInjector.provision(ConstructorInjector.java:107)
at com.google.inject.internal.ConstructorInjector.construct(ConstructorInjector.java:88)
at com.google.inject.internal.ConstructorBindingImpl$Factory.get(ConstructorBindingImpl.java:269)
at com.google.inject.internal.InjectorImpl$3$1.call(InjectorImpl.java:1005)
at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1051)
at com.google.inject.internal.InjectorImpl$3.get(InjectorImpl.java:1001)
at com.google.inject.assistedinject.FactoryProvider2.invoke(FactoryProvider2.java:665)
at $Proxy6.create(Native Method)
at eu.stosdev.MainActivity$1.doInBackground(MainActivity.java:25)
at eu.stosdev.MainActivity$1.doInBackground(MainActivity.java:20)
これらの作成操作が UI スレッドで実行される場合、両方の PlayerImpl オブジェクトが適切に作成されます。Google Guice を使い始めたばかりで、インジェクターを使用してオブジェクトを作成するとすべて問題なく、factory を使用しない理由がわかりません。スレッドでファクトリを使用する方法はありますか?