AndroidAnnotations Framework - Love it or hate it

AndroidAnnotations Framework - Love it or hate it

An AndroidAnnotations framework intro. Pros and cons.

2e31903e37e8566e7cce070a04a37e7a?s=128

Andrei Verdes

April 23, 2016
Tweet

Transcript

  1. AndroidAnnotations Framework Love it or hate it Andrei Verdes Maxcode

    23 April 2016, Iasi
  2. None
  3. Sponsors

  4. Sponsors

  5. Java Annotations @Something

  6. Annotations Processor MyProcessor extends AbstractProcessor{…}

  7. The AA Framework

  8. Enhanced classes package ro.androidiasi.codecamp.main; @E<something> public class EnhancedClass{ … }

    AA will generate… package ro.androidiasi.codecamp.main; public final class EnhancedClass_ extends EnhancedClass{ … }
  9. Enhanced classes package ro.androidiasi.codecamp.main; @E<something> public class EnhancedClass{ … }

    AA will generate… package ro.androidiasi.codecamp.main; public final class EnhancedClass_ extends EnhancedClass{ … }
  10. BoringActivity vs EnhancedActivity

  11. BoringActivity public class BoringActivityextends Activity { @Override protected void onCreate(Bundle

    savedInstanceState) { super.onCreate(savedInstanceState); this.setContentView(R.layout.activity_main); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main_menu, menu); return true; } }
  12. BoringActivity - layout public class BoringActivityextends Activity { @Override protected

    void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.setContentView(R.layout.activity_main); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main_menu, menu); return true; } }
  13. BoringActivity - menu public class BoringActivityextends Activity { @Override protected

    void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.setContentView(R.layout.activity_main); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main_menu, menu); return true; } }
  14. Let’s enhance an Activity

  15. EnhancedActivity @OptionsMenu(R.menu.main_menu) @EActivity(R.layout.activity_main) public class EnhancedActivity extends Activity { //that’s

    it :D }
  16. EnhancedActivity - layout @OptionsMenu(R.menu.main_menu) @EActivity(R.layout.activity_main) public class EnhancedActivity extends Activity

    { //that’s it :D }
  17. EnhancedActivity - menu @OptionsMenu(R.menu.main_menu) @EActivity(R.layout.activity_main) public class EnhancedActivity extends Activity

    { //that’s it :D }
  18. EnhancedActivity @OptionsMenu(R.menu.main_menu) @EActivity(R.layout.activity_main) public class EnhancedActivity extends Activity { //that’s

    it :D }
  19. BoringActivity - views private TabLayout mTabLayout; private ViewPager mViewPager; @Override

    protected void onCreate(…) { super.onCreate(savedInstanceState); mTabLayout = (TabLayout) findViewById(R.id….); mViewPager = (ViewPager) findViewById(R.id…); }
  20. BoringActivity - views private TabLayout mTabLayout; private ViewPager mViewPager; @Override

    protected void onCreate(…) { super.onCreate(savedInstanceState); this.setContentView(R.layout…); mTabLayout = (TabLayout) findViewById(R.id…); mViewPager = (ViewPager) findViewById(R.id…); }
  21. EnhancedActivity - views @ViewById(R.id…) TabLayout mTabLayout; @ViewById(R.id…) ViewPager mViewPager; And

    that’s it! :D
  22. EnhancedActivity - views @ViewById(R.id…) TabLayout mTabLayout; @ViewById(R.id…) ViewPager mViewPager; And

    that’s it! :D
  23. BoringActivity - fields private CodecampApp mCodecampApp; private SessionsAdapter mSessionsAdapter; private

    LayoutInflater mLayoutInflater; mCodecampApp = (CodecampApp) this.getApplication(); mSessionsAdapter= new SessionsAdapter(); mLayoutInflater= (LayoutInflater) this.getSystemService( Context.LAYOUT_INFLATER_SERVICE);
  24. BoringActivity - fields private CodecampApp mCodecampApp; private SessionsAdapter mSessionsAdapter; private

    LayoutInflater mLayoutInflater; mCodecampApp = (CodecampApp) this.getApplication(); mSessionsAdapter= new SessionsAdapter(); mLayoutInflater= (LayoutInflater) this.getSystemService( Context.LAYOUT_INFLATER_SERVICE);
  25. BoringActivity – menu item private MenuItem mMenuSearch; @Override … onCreateOptionsMenu(Menu

    menu) { getMenuInflater().inflate(R.menu…., menu); mMenuSearch = menu.findItem(R.id.menu_search); return true; }
  26. BoringActivity – menu item private MenuItem mMenuSearch; @Override … onCreateOptionsMenu(Menu

    menu) { getMenuInflater().inflate(R.menu…, menu); mMenuSearch = menu.findItem(R.id…); return true; }
  27. EnhancedActivity - application @App CodecampApp mCodecampApp; @Bean SessionsAdapter mSessionsAdapter; @SystemService

    LayoutInflater mLayoutInflater; @OptionsMenuItem(R.id.menu_search) MenuItem mMenuSearch;
  28. EnhancedActivity - beans @App CodecampApp mCodecampApp; @Bean SessionsAdapter mSessionsAdapter; @SystemService

    LayoutInflater mLayoutInflater; @OptionsMenuItem(R.id.menu_search) MenuItem mMenuSearch;
  29. EnhancedActivity - services @App CodecampApp mCodecampApp; @Bean SessionsAdapter mSessionsAdapter; @SystemService

    LayoutInflater mLayoutInflater; @OptionsMenuItem(R.id.menu_search) MenuItem mMenuSearch;
  30. EnhancedActivity - menu item @App CodecampApp mCodecampApp; @Bean SessionsAdapter mSessionsAdapter;

    @SystemService LayoutInflater mLayoutInflater; @OptionsMenuItem(R.id.menu_search) MenuItem mMenuSearch;
  31. EnhancedActivity - fields @App CodecampApp mCodecampApp; @Bean SessionsAdapter mSessionsAdapter; @SystemService

    LayoutInflater mLayoutInflater; @OptionsMenuItem(R.id.menu_search) MenuItem mMenuSearch; • And that’s it! :D
  32. BoringActivity - extras public static final String TAG_EXTRA = "tag";

    private String mSomeString; mSomeString = getIntent().getStringExtra(TAG_EXTRA); public static void start(Context pContext, String pSomeString){ Intent intent = new Intent(pContext, BoringActivity.class); intent.putExtra(TAG_EXTRA, pSomeString); pContext.startActivity(intent); }
  33. BoringActivity - extras public static final String TAG_EXTRA = "tag";

    private String mSomeString; mSomeString = getIntent().getStringExtra(TAG_EXTRA); public static void start(Context pContext, String pSomeString){ Intent intent = new Intent(pContext, BoringActivity.class); intent.putExtra(TAG_EXTRA, pSomeString); pContext.startActivity(intent); }
  34. BoringActivity - extras public static final String TAG_EXTRA = "tag";

    private String mSomeImportantString; mSomeString = getIntent().getStringExtra(TAG_EXTRA); public static void start(Context pContext, String pSomeString){ Intent intent = new Intent(pContext, BoringActivity.class); intent.putExtra(TAG_EXTRA, pSomeString); pContext.startActivity(intent); }
  35. BoringActivity - extras public static final String TAG_EXTRA = "tag";

    private String mSomeImportantString; mSomeString = getIntent().getStringExtra(TAG_EXTRA); public static void start(Context pContext, String pSomeString){ Intent intent = new Intent(pContext, BoringActivity.class); intent.putExtra(TAG_EXTRA, pSomeString); pContext.startActivity(intent); }
  36. EnhancedActivity - extras @Extra String mSomeString; public static void start(Context

    pContext, String pSomeString){ EnhancedActivity_ .intent(pContext) .mSomeString(pSomeString) .start(); }
  37. EnhancedActivity - summary @OptionsMenu(R.menu.main_menu) @EActivity(R.layout.activity_main) public class EnhancedActivityextends Activity {

    @ViewById(R.id…) TabLayout mTabLayout; @ViewById(R.id…) ListView mListView; @App CodecampApp mCodecampApp; @Bean SessionsAdapter mSessionsAdapter; @SystemService LayoutInflater mLayoutInflater; @Extra String mSomeImportantString ; @OptionsMenuItem(R.id…)MenuItemmMenuSearch; }
  38. Class annotations • @EBean • @EService or @EIntentService • @EView

    or @EViewGroup • @EActivity or @EFragment
  39. Method annotations - lifecycle 1. @AfterExtras public void afterExtrasInject(){...} 2.

    @AfterInject public void afterMembersInject(){...} 3. @AfterViews public void afterViewsInjecta(){...}
  40. Method annotations - lifecycle 1. @AfterExtras public void afterExtrasInject(){...} 2.

    @AfterInject public void afterMembersInject(){...} 3. @AfterViews public void afterViewsInjecta(){...}
  41. Method annotations - lifecycle 1. @AfterExtras public void afterExtrasInject(){...} 2.

    @AfterInject public void afterMembersInject(){...} 3. @AfterViews public void afterViewsInjecta(){...}
  42. Method annotations – events @Click(R.id.button) public void onButtonClicked() { Toast.makeText(...).show();

    } @LongClick(R.id.button) public void onButtonLongClicked(){ Toast.makeText(...).show(); } @ItemClick(R.id.list_view) public void onSessionsListItemClicked(Session pSession){ Toast.makeText(...).show(); } @TextChange(R.id.edit_text) public void onTextChangeEditText(...) { Toast.makeText(...).show(); } @OptionsItem(R.id.menu_search) public void onSearchMenuItemClicked() { Toast.makeText(...).show(); }
  43. Method annotations – events @Click(R.id.button) public void onButtonClicked() { Toast.makeText(...).show();

    } @LongClick(R.id.button) public void onButtonLongClicked(){ Toast.makeText(...).show(); } @ItemClick(R.id.list_view) public void onSessionsListItemClicked(Session pSession){ Toast.makeText(...).show(); } @TextChange(R.id.edit_text) public void onTextChangeEditText(...) { Toast.makeText(...).show(); } @OptionsItem(R.id.menu_search) public void onSearchMenuItemClicked() { Toast.makeText(...).show(); }
  44. Method annotations – events @Click(R.id.button) public void onButtonClicked() { Toast.makeText(...).show();

    } @LongClick(R.id.button) public void onButtonLongClicked(){ Toast.makeText(...).show(); } @ItemClick(R.id.list_view) public void onSessionsListItemClicked(Session pSession){ Toast.makeText(...).show(); } @TextChange(R.id.edit_text) public void onTextChangeEditText(...) { Toast.makeText(...).show(); } @OptionsItem(R.id.menu_search) public void onSearchMenuItemClicked() { Toast.makeText(...).show(); }
  45. Method annotations – events @Click(R.id.button) public void onButtonClicked() { Toast.makeText(...).show();

    } @LongClick(R.id.button) public void onButtonLongClicked(){ Toast.makeText(...).show(); } @ItemClick(R.id.list_view) public void onSessionsListItemClicked(Session pSession){ Toast.makeText(...).show(); } @TextChange(R.id.edit_text) public void onTextChangeEditText(...) { Toast.makeText(...).show(); } @OptionsItem(R.id.menu_search) public void onSearchMenuItemClicked() { Toast.makeText(...).show(); }
  46. Method annotations – events @Click(R.id.button) public void onButtonClicked() { Toast.makeText(...).show();

    } @LongClick(R.id.button) public void onButtonLongClicked(){ Toast.makeText(...).show(); } @ItemClick(R.id.list_view) public void onSessionsListItemClicked(Session pSession){ Toast.makeText(...).show(); } @TextChange(R.id.edit_text) public void onTextChangeEditText(...) { Toast.makeText(...).show(); } @OptionsItem(R.id.menu_search) public void onSearchMenuItemClicked() { Toast.makeText(...).show(); }
  47. Method annotations - threading @Background public void onBackgroundGetSessionsList(){ List<Session> sessionsList

    = this.mCodecampRestClient.getSessions(); this.onUiThreadUpdateSessionsList(sessionsList); } @Background public void onBackgroundGetSessionById(String pSessionId){ Session session = this.mCodecampRestClient.getSession(pSessionId); this.onUiThreadUpdateSession(session); } @UiThread public void onUiThreadUpdateSessionsList(List<Session> pSessionList){ this.mSessionsAdapter.setSessionsList(pSessionList); this.mSessionsAdapter.notifyDataSetChanged(); } @UiThread public void onUiThreadUpdateSession(Session pSession){ this.mSessionsAdapter.setSession(pSession); this.mSessionsAdapter.notifyDataSetChanged(); }
  48. Method annotations - threading @Background public void onBackgroundGetSessionsList(){ List<Session> sessionsList

    = this.mCodecampRestClient.getSessions(); this.onUiThreadUpdateSessionsList(sessionsList); } @Background public void onBackgroundGetSessionById(String pSessionId){ Session session = this.mCodecampRestClient.getSession(pSessionId); this.onUiThreadUpdateSession(session); } @UiThread public void onUiThreadUpdateSessionsList(List<Session> pSessionList){ this.mSessionsAdapter.setSessionsList(pSessionList); this.mSessionsAdapter.notifyDataSetChanged(); } @UiThread public void onUiThreadUpdateSession(Session pSession){ this.mSessionsAdapter.setSession(pSession); this.mSessionsAdapter.notifyDataSetChanged(); }
  49. REST Client - SpringAndroid @Rest(rootUrl = "https://awesomecodecampbackend.com"…) public interface CodecampRestClient{

    @Get("/sessions") List<Session> getSessions(); @Get("/sessions/{sessionId}") Session getSession(@Path String sessionId); }
  50. REST Client - SpringAndroid @Rest(rootUrl = "https://awesomecodecampbackend.com”…) public interface CodecampRestClient{

    @Get("/sessions") List<Session> getSessions(); @Get("/sessions/{sessionId}") Session getSession(@Path String sessionId); }
  51. Tips and tricks

  52. Beware of the AA lifecycle multiple calls @EActivity public abstract

    class ActivityA extends Activity{ @AfterViews public void afterViews(){} } @EActivity public static class ActivityB extends ActivityA { @AfterViews public void afterViews(){} } @EActivity public static class ActivityC extends ActivityB { @AfterViews public void afterViews(){} }
  53. Beware of the AA lifecycle multiple calls @EActivity public abstract

    class ActivityA extends Activity{ @AfterViews public void afterViews(){} } @EActivity public abstract static class ActivityB extends ActivityA { @AfterViews public void afterViews(){} } @EActivity public static class ActivityC extends ActivityB { @AfterViews public void afterViews(){} }
  54. Beware of the AA lifecycle multiple calls @EActivity public abstract

    class ActivityA extends Activity{ @AfterViews public void afterViews(){} } @EActivity public abstract class ActivityB extends ActivityA { @AfterViews public void afterViews(){} } @EActivity public class ActivityC extends ActivityB { @AfterViews public void afterViews(){} }
  55. Beware of the AA lifecycle multiple calls public final class

    ActivityC_ extends ActivityC...{ @Override public void onViewChanged (HasViews hasViews){ afterViews(); afterViews(); afterViews(); } }
  56. Beware of the AA lifecycle multiple calls public final class

    ActivityC_ extends ActivityC...{ @Override public void onViewChanged (HasViews hasViews){ afterViews(); afterViews(); afterViews(); } }
  57. Solution Use @AfterViews only once @EActivity public abstract class ActivityA

    extends Activity{ @AfterViews public void afterViewsInject(){ this.afterViews(); } @CallSuper public void afterViews(){} }
  58. Solution Use @AfterViews only once @EActivity public abstract class ActivityA

    extends Activity{ @AfterViews public void afterViewsInject(){ this.afterViews(); } @CallSuper public void afterViews(){} }
  59. Beware of the layout injection @EViewGroup(R.layout.view_awesome) public class ViewA extends

    LinearLayout { } @EViewGroup public class ViewB extends ViewA { }
  60. Beware of the layout injection @EViewGroup(R.layout.view_awesome) public class ViewA extends

    LinearLayout { } @EViewGroup public class ViewB extends ViewA { }
  61. Solution Always add your layout @EViewGroup(R.layout.view_awesome) public class ViewA extends

    LinearLayout { } @EViewGroup(R.layout.view_awesome) public class ViewB extends ViewA { }
  62. Method naming @Background void onBackground*...(){} @UiThread void onUiThread*...(){} @UiThread(delay=...) void

    onUiThreadDelayed*...(){} @Click void onSomethingClicked(){} @ItemClick void onSomethingItemClicked(){} @OptionsItem void onOptionsItemClicked(){}
  63. Method naming @Background void onBackground*...(){} @UiThread void onUiThread*...(){} @UiThread(delay=...) void

    onUiThreadDelayed*...(){} @Click void onSomethingClicked(){} @ItemClick void onSomethingItemClicked(){} @OptionsItem void onOptionsItemClicked(){}
  64. Method naming @Background void onBackground*...(){} @UiThread void onUiThread*...(){} @UiThread(delay=...) void

    onUiThreadDelayed*...(){} @Click void onSomethingClicked(){} @ItemClick void onSomethingItemClicked(){} @OptionsItem void onOptionsItemClicked(){}
  65. Method naming @Background void onBackground*...(){} @UiThread void onUiThread*...(){} @UiThread(delay=...) void

    onUiThreadDelayed*...(){} @Click void onSomethingClicked(){} @ItemClick void onSomethingItemClicked(){} @OptionsItem void onOptionsItemClicked(){}
  66. Method naming @Background void onBackground*...(){} @UiThread void onUiThread*...(){} @UiThread(delay=...) void

    onUiThreadDelayed*...(){} @Click void onSomethingClicked(){} @ItemClick void onSomeListItemClicked(){} @OptionsItem void onOptionsItemClicked(){}
  67. Method naming @Background void onBackground*...(){} @UiThread void onUiThread*...(){} @UiThread(delay=...) void

    onUiThreadDelayed*...(){} @Click void onSomethingClicked(){} @ItemClick void onSomeListItemClicked(){} @OptionsItem void onSomeOptionsItemClicked(){}
  68. Beware of memory leaks @UiThread(delay = 5000) public void onUiThreadDelayedSomething(){

    this.mActivity.finish(); }
  69. Solution Use WeakReferences @UiThread(delay = 5000) public void onUiThreadDelayedSomething (WeakReference<Activity>

    pActivityWeakReference){ if(pActivityWeakReference.get() != null){ pActivityWeakReference.get().finish(); } }
  70. Beware of big projects • Classic Java errors can stop

    AA from generating your enhanced classes • The error window won’t report more than 101 errors • Your actual error will get lost in the compiler stacktrace
  71. Solution 1.1 • Start a question on StackOverflow • Write

    a regex that removes all of your “_;” ending imports • Fix the actual error and imports (no vcs? try local history from IntelliJ) • Make project • Voila! • Start a bounty on your StackOverflow error
  72. Solution 1.1 • Start a question on StackOverflow • Write

    a regex that removes all of your “_;” ending imports • Fix the actual error and imports (no vcs? try local history from IntelliJ) • Make project • Voila! • Start a bounty on your StackOverflow error
  73. Solution 1.1 • Start a question on StackOverflow • Write

    a regex that removes all of your “_;” ending imports • Fix the actual error and imports (no vcs? try local history from IntelliJ) • Make project • Voila! • Start a bounty on your StackOverflow error
  74. Solution 1.1 • Start a question on StackOverflow • Write

    a regex that removes all of your “_;” ending imports • Fix the actual error and imports (no vcs? try local history from IntelliJ) • Make project • Voila! • Start a bounty on your StackOverflow error
  75. Solution 1.1 • Start a question on StackOverflow • Write

    a regex that removes all of your “_;” ending imports • Fix the actual error and imports (no vcs? try local history from IntelliJ) • Make project • Voila! • Start a bounty on your StackOverflow error
  76. Solution 1.1 • Start a question on StackOverflow • Write

    a regex that removes all of your “_;” ending imports • Fix the actual error and imports (no vcs? try local history from IntelliJ) • Make project • Voila! • Start a bounty on your StackOverflow error
  77. But wait, there’s more… • Someone answers the question... •

    Change the javac compiler’s maxerr parameter to higher value (-Xmaxerrs 400 -Xmaxwarns 1000)
  78. But wait, there’s more… • Someone answers the question... •

    Change the javac compiler’s maxerr parameter to higher value (-Xmaxerrs 400 -Xmaxwarns 1000)
  79. But wait, there’s more… • Someone answers the question... •

    Change the javac compiler’s maxerr parameter to higher value (-Xmaxerrs 400 -Xmaxwarns 1000) • https://stackoverflow.com/questions/35314856/an droid-studio-messages- window/36628587#36628587
  80. AndroidAnnotations 4.0 march 2016

  81. AA 4.0 • Major refactoring • Support for Parcelables with

    parceler.org • Plugins • @AwesomeAnotation • AwesomePlugin extends AndroidAnnotationsPlugin • Let the fun begin!
  82. To use it or not to use it? That is

    the question! Q&A?
  83. None
  84. None
  85. AndroidIasi.ro

  86. AndroidAnnotationsFramework – Love it or hate it Andrei Verdes Maxcode

    23 April 2016, Iasi Please fill the online evaluation form after event