@App instance = null, from @EBean #228
Description
Activity
and a suggestion:
Something that automatically bind adapters.Before:
@ViewById ListView personList; @Bean PersonListAdapter adapter; @AfterViews void bindAdapter() { personList.setAdapter(adapter); }After:
@ViewById ListView personList; @Adapter PersonListAdapter personListAdapter;or:
@ViewById(adapter = PersonListAdapter.class) ListView personList;Hello @stewunknown.
Regarding your first issue : the main problem here is that the
getApplication()method is only available onActivity(and service), not on all kinds of context. Context hasgetApplicationContext(), but there is no guarantee that it returns yourApplicationinstance, although it may be the case.See getApplication() vs. getApplicationContext().
Using
RootContextinjects theContextwhich was used to build the bean. If you inject the bean in anApplicationannotated with@EApplication, it will work. If your bean is a singleton, we usecontext.getApplicationContext()to prevent memory leaks. In this case, it may also work, but there is no guarantee that your application instance may be injected.I'm starting to think we could make it work by storing the Application instance as a singleton in a field of the Application generated subclass, and access it from there. This would fix your issue, and you could use
@Appeverywhere.Regarding the second issue, this is something completely different. It looks like a really good idea, but please create a separate issue :) .
With #352 we should be able to remove
@Appand provide a unified annotation to inject, that would work for theApplicationclass from anywhere.Moving forward without waiting for #352:
Validation of
@App- We should read the application class from the manifest, and retrieve the corresponding element
- If the application class is set in the manifest, it's a class that terminates with "" and there exist a superclass with the same name without the "" that is annotated with
@EApplication, and if the field is not private and used in a class that contains an enhancing annotation (except `@EApplication).
Generated code
In the annotated application:
public class MyApplication_ extends MyApplication { private MyApplication_ instance; public static MyApplication_ getInstance() { return instance; } @Override public onCreate() { super.onCreate(); instance = this; } }
In a class that needs
MyApplication_:myApplication = MyApplication_.getInstance();
A few additional notes:
- The
@Appannotated field will now only allow injection of@EApplicationannotated class. It didn't make much sense to injectApplicationanyway, norContext. - The generated
Applicationsubclass will have a static setter to set / update its value for testing.
- The
Here's what I came up with:
public final class MyApp_ extends MyApp { private static MyApp INSTANCE_; public static MyApp getInstance() { return INSTANCE_; } /** * Visible for testing purposes * */ public static void setForTesting(MyApp application) { INSTANCE_ = application; } @Override public void onCreate() { INSTANCE_ = this; super.onCreate(); } }
@Appgenerates the following code in the init methods :app = SampleRoboApplication_.getInstance();This means we can inject the application in any component :)
- added a commit that references this issue
on Feb 28, 2013
I will try to explain with comments.
Generated Code with @app BaseApp baseApp;:
Generated Code with @rootcontext BaseApp baseApp;: