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

Generate one common class for builders #883

Description

@Artyomcool

This code depends on generated class:

FragmentA fragment = new Fragment_();

It would be a big problem, if it is the only place. E.g. I want to make my tests independent from AA, or drop AA at all in the future (don't believe that it is possible for me, but still :)).
Maybe it is better to have just one class for constructions like:

FragmentA fragment = GeneratedClasses.create(FragmentA.class);

Is it possible?

Activity

  1. yDelouis commented on Jan 13, 2014

    @yDelouis
    Contributor

    You will still have to declare generated class in AndroidManifest.xml.

  2. Artyomcool commented on Jan 13, 2014

    @Artyomcool
    Author

    Oh, true. But rewriting manifest is much simplier. Moreover, actualy I'm not sure that there is some real need for declare them in the manifest - gradle already processes manifest and generating new one - there is no problem to inject correct components during this step.

  3. Artyomcool commented on Mar 17, 2014

    @Artyomcool
    Author

    Moreover, you don't need to declare generated class in manifest in situations:

    1. The class is a fragment
    2. The class is a bean
    3. The class is a view
      E.g. it is awkward:
    view = CallInfoItem_.build(parent.getContext());
    

    Much better would be something like this:

    view = GeneratedClasses.createView(CallInfoItem.class, parent.getContext());
    

    What do you think? If you do like such way, I'll try to implement it.

  4. DayS commented on Mar 17, 2014

    @DayS
    Contributor

    I'm also currently thinking of a kin of factory for generated class based on the original one. I'd like to get ride of direct call to generated class in the code (ie: MyActivity_.intent(...).startActivity())

  5. Artyomcool commented on Mar 17, 2014

    @Artyomcool
    Author

    Yep. I'm not sure that there is some way to avoid generated intent builders, but maybe we will get some clue while implementing other classes. So, I'll try to implement some cases in order to look deeper into the problem and make a PR, ok?

  6. Artyomcool commented on Mar 17, 2014

    @Artyomcool
    Author

    It also will be useful, if the factory class will have some way to set a strategy of instantiation. In this case it will be easier to mock up objects for testing.

  7. DayS commented on Mar 17, 2014

    @DayS
    Contributor

    I know that @jeremiemartinez and @fredszaq worked on a way to have a cleaner injection mechanism. They're also based on a kind of factory to do this. It may be great to merge these two features.

  8. fredszaq commented on Mar 17, 2014

    @fredszaq

    Indeed both ideas seems very much alike, you can take a look at https://github.com/fredszaq/androidannotations/tree/inject for the work we've been doing on injection.

    In any case, not having to explicitly use a generated class in java code seems to be a good thing !

  9. Artyomcool commented on Mar 17, 2014

    @Artyomcool
    Author

    Yeah, looks great! But actually I would like to do it in another way - iterate over array while looking for creator is not the best idea, map of class to creator would be better. I'll take a closer look on this week, it is a very good point to start at. Thanks.

  10. yDelouis commented on Mar 17, 2014

    @yDelouis
    Contributor

    I started to work on this too, but was stuck with IntentBuilders of generated activities.
    I used @Artyomcool way of doing this, with static methods of a factory class and reflexion.
    You can see the it here.

  11. Artyomcool commented on Mar 18, 2014

    @Artyomcool
    Author

    I'll try to implement the same thing but without reflections. Looks like I need to make @fredszaq and @yDelouis approaches work together to achieve this.
    As for IntentBuilders I don't see the direct way. But what if reimplement @Extra annotation for working with POJO? I mean something like that:

    @EExtra
    class Extra {
      String stringExtra;
      int intExtra;
    }
    
    @EActivity 
    class SomeActivity extends Activity {
    
      @Extra
      Extra extra;
    
    }
    

    This allows us to make generic intent builder:

    IntentBuilder<Extra> builder = AA.getBuilder(SomeActivity.class, Extra.class);
    

    It is just an idea, so, tell me if I'm missing something.

  12. DayS commented on Mar 18, 2014

    @DayS
    Contributor

    Don't forget we have to keep retro-compatibility with AA < 3.1
    So we're not going to drop the inner intent builder in generated classes. At least, not now.

    That being said, in your suggested solution you're still using IntentBuilder<Extra> which is a generated inner-class. With this, you're not using the generated class but the generated inner-class. Not what we're looking for :)

    I'll try to find a solution this week, but I'm afraid there is no elegant solution. Right now, I only thinking of using one generated class (the factory) or using reflection in the factory.

  13. Artyomcool commented on Mar 18, 2014

    @Artyomcool
    Author

    Hey, I'm not suggesting to drop compatibility :) Just to add a new way for creating intents, without removing the old one.
    And IntentBuilder<Extra> is not supposed to be generated class, it is suppose to be an interface with setExtra method.

  14. WonderCsabo commented on Apr 7, 2014

    @WonderCsabo
    Member

    @fredszaq what are your custom injection does actually? Can it help #918 for example? Are you planning to finish the feature?

  15. PerfectCarl commented on Apr 7, 2014

    @PerfectCarl
    Contributor

    Your solution is way better than what I tried to propose in #431
    I love this idea.
    And I second the less reflection, the better approach: offering a feature that improves maintainability (and fixes some Eclipse quirks) but impairs performance for the end user is a real dilemma :)

  16. 6 remaining items

  17. added this to the 3.1 milestone on May 11, 2014
  18. PerfectCarl commented on May 28, 2014

    @PerfectCarl
    Contributor

    @jeremiemartinez Could you provide us a example of code using your feature?

  19. PerfectCarl commented on May 30, 2014

    @PerfectCarl
    Contributor

    I built @jeremiemartinez inject branch.

    So far, this what I could understand:

    • there are two new annotations @Creates and @Creator
    • the @EApplication has been modified to take a list of creator
    • it works only to instantiate EBean

    So you create a Creator interface

    @ECreator()
    public interface MyCreator extends Creator {
    
        @Creates(MyBean.class)
        MyBean createMyBean(Context context);
    
    }

    that you reference in your application

    @EApplication(creators = MyCreator.class)
    public class MyApplication extends Application {
    
    }

    and then you get to use the CreatorFacade that let you create enhanced beans

    @EActivity
    public class MyActivity extends Activity {
    
        @Bean
        MyBean aBean;
    
        @AfterViews
        void init() {
            MyBean bean = CreatorFacade.getBean(MyBean.class, this);
            if (bean != null) {
                System.err.println("This is a MyBean_. Yes for real!");
            }
        }
    
    }

    Note that the old @Bean work also and the generated code will use the new CreatorFacade class.

    Here's the complete test project (with generated classes).

    The feature is pretty neat, unfortunately it doesn't work for the bulk of my use cases:

    • with EFragment
    • simple MyActivity.class to MyActivity_.class conversion that are used when you open a new activity.

    That being said those features can be added :)

  20. WonderCsabo commented on May 30, 2014

    @WonderCsabo
    Member

    Since Dagger now can be used in conjunction with AA, we should provide integratation with it and let Dagger inject our @EBeans.

    BTW, this injection thing should be in a separate issue, it has little to do with builder classes.

  21. DayS commented on May 31, 2014

    @DayS
    Contributor

    Tell me if I'm wrong but this issue should be closed now that #994 has been merged. Am I right ?

  22. WonderCsabo commented on May 31, 2014

    @WonderCsabo
    Member

    No. This is about creating one builder class which can create instances of the generated classes, so we do not have to reference generated code. See the OP and initial discussion. BTW #1017 is little bit wants the same. We should clarify the scope of this issue and the other.

  23. DayS commented on Jun 2, 2014

    @DayS
    Contributor

    Right, but I think this feature will be included in the other PR in order to handle your case 4 (ie: using EBean in non-enhanced classes).

  24. modified the milestones: 3.1, 3.2 on Sep 20, 2014
  25. removed this from the 3.2 milestone on Nov 12, 2014
  26. WonderCsabo commented on Jun 9, 2015

    @WonderCsabo
    Member

    @Artyomcool this is the same as #1017 am i right?

  27. WonderCsabo commented on Jun 9, 2015

    @WonderCsabo
    Member

    BTW, we could modify the manifest file easily in Gradle and Maven builds by replacing the Activity/Service names with the generated ones. With this and the builder, we cold completely get rid of "_"s. I think that would be cool.

  28. WonderCsabo commented on Jun 9, 2015

    @WonderCsabo
    Member

    Another idea: we could override startActivity etc. methods, and use the common builder in that. That way the user just have to call startActivity(this, new Intent(Annotated.class), and startActivity will modify the Intent to use the Annotated_.class. However in that way the user could not use the generated setter methods for @Extra etc, and requires more boilerplate then the current solution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions