Upgrade to Pro — share decks privately, control downloads, hide ads and more …

AndroidAnnotations Framework - Love it or hate it

AndroidAnnotations Framework - Love it or hate it

An AndroidAnnotations framework intro. Pros and cons.

Andrei Verdes

April 23, 2016
Tweet

More Decks by Andrei Verdes

Other Decks in Technology

Transcript

  1. 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{ … }
  2. 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{ … }
  3. 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; } }
  4. 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; } }
  5. 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; } }
  6. 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…); }
  7. 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…); }
  8. 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);
  9. 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);
  10. BoringActivity – menu item private MenuItem mMenuSearch; @Override … onCreateOptionsMenu(Menu

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

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

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

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

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

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

    LayoutInflater mLayoutInflater; @OptionsMenuItem(R.id.menu_search) MenuItem mMenuSearch; • And that’s it! :D
  17. 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); }
  18. 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); }
  19. 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); }
  20. 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); }
  21. EnhancedActivity - extras @Extra String mSomeString; public static void start(Context

    pContext, String pSomeString){ EnhancedActivity_ .intent(pContext) .mSomeString(pSomeString) .start(); }
  22. 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; }
  23. Method annotations - lifecycle 1. @AfterExtras public void afterExtrasInject(){...} 2.

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

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

    @AfterInject public void afterMembersInject(){...} 3. @AfterViews public void afterViewsInjecta(){...}
  26. 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(); }
  27. 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(); }
  28. 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(); }
  29. 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(); }
  30. 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(); }
  31. 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(); }
  32. 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(); }
  33. REST Client - SpringAndroid @Rest(rootUrl = "https://awesomecodecampbackend.com"…) public interface CodecampRestClient{

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

    @Get("/sessions") List<Session> getSessions(); @Get("/sessions/{sessionId}") Session getSession(@Path String sessionId); }
  35. 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(){} }
  36. 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(){} }
  37. 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(){} }
  38. Beware of the AA lifecycle multiple calls public final class

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

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

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

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

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

    LinearLayout { } @EViewGroup public class ViewB extends ViewA { }
  44. 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 { }
  45. Method naming @Background void onBackground*...(){} @UiThread void onUiThread*...(){} @UiThread(delay=...) void

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

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

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

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

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

    onUiThreadDelayed*...(){} @Click void onSomethingClicked(){} @ItemClick void onSomeListItemClicked(){} @OptionsItem void onSomeOptionsItemClicked(){}
  51. Solution Use WeakReferences @UiThread(delay = 5000) public void onUiThreadDelayedSomething (WeakReference<Activity>

    pActivityWeakReference){ if(pActivityWeakReference.get() != null){ pActivityWeakReference.get().finish(); } }
  52. 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
  53. 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
  54. 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
  55. 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
  56. 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
  57. 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
  58. 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
  59. But wait, there’s more… • Someone answers the question... •

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

    Change the javac compiler’s maxerr parameter to higher value (-Xmaxerrs 400 -Xmaxwarns 1000)
  61. 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
  62. AA 4.0 • Major refactoring • Support for Parcelables with

    parceler.org • Plugins • @AwesomeAnotation • AwesomePlugin extends AndroidAnnotationsPlugin • Let the fun begin!
  63. AndroidAnnotationsFramework – Love it or hate it Andrei Verdes Maxcode

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