Skip to content
This repository was archived by the owner on Feb 26, 2023. It is now read-only.

@App instance = null, from @EBean #228

Description

@fc1943s

I will try to explain with comments.

Generated Code with @app BaseApp baseApp;:

private void init_() {
    //context_ is not an activity. context.getApplicationContext() is called on getInstance. 
    if (context_ instanceof Activity) {
        Activity activity = ((Activity) context_);
        baseApp = ((BaseApp) activity.getApplication());
    }
    init();
}

Generated Code with @rootcontext BaseApp baseApp;:

private void init_() {
    if (context_ instanceof Activity) {
        Activity activity = ((Activity) context_);
    }
    //here works.
    if (context_ instanceof BaseApp) {
        baseApp = ((BaseApp) context_);
    }
    init();
}

Activity

  1. fc1943s commented on Jun 12, 2012

    @fc1943s
    Author

    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;
    
  2. pyricau commented on Jun 12, 2012

    @pyricau
    Contributor

    Hello @stewunknown.

    Regarding your first issue : the main problem here is that the getApplication() method is only available on Activity (and service), not on all kinds of context. Context has getApplicationContext(), but there is no guarantee that it returns your Application instance, although it may be the case.

    See getApplication() vs. getApplicationContext().

    Using RootContext injects the Context which was used to build the bean. If you inject the bean in an Application annotated with @EApplication, it will work. If your bean is a singleton, we use context.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 @App everywhere.

    Regarding the second issue, this is something completely different. It looks like a really good idea, but please create a separate issue :) .

  3. pyricau commented on Oct 25, 2012

    @pyricau
    Contributor

    With #352 we should be able to remove @App and provide a unified annotation to inject, that would work for the Application class from anywhere.

  4. pyricau commented on Nov 25, 2012

    @pyricau
    Contributor

    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();
  5. ghost assigned on Feb 27, 2013
  6. pyricau commented on Feb 28, 2013

    @pyricau
    Contributor

    A few additional notes:

    • The @App annotated field will now only allow injection of @EApplication annotated class. It didn't make much sense to inject Application anyway, nor Context.
    • The generated Application subclass will have a static setter to set / update its value for testing.
  7. pyricau commented on Feb 28, 2013

    @pyricau
    Contributor

    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();
        }
    
    }

    @App generates the following code in the init methods : app = SampleRoboApplication_.getInstance();

    This means we can inject the application in any component :)

  8. added a commit that references this issue on Feb 28, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions