I'm creating Android project using RoboGuice 2.0 with help from Guice Extension - Assisted Inject. Right now I'm facing problem with injecting Context via factory on non UI thread.
Sample Project with show my issue:
Person interface:
public interface Person {
}
Person implementation:
@AssistedInject
public PersonImpl(@Assisted String name, @Assisted int age, Context context) {
}
@Inject
public PersonImpl(Context context) {
}
Perfon factory:
Person create(@Assisted String name, @Assisted int age);
Module:
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));
}
}
MainActivity:
@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();
}
When AsyncTask is executed injector create Person object. This operation works fine and as expected return PersonImpl object. However when factory try to create new Person object this exception is raised:
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)
If those creation operations are preformed on UI Thread both PlayerImpl object are created properly. I just started using Google Guice and I'm confused why when object is created using injector everything is fine, but using factory not. Is there any good solution how to use factory on threads?