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

Android Infrastructure Overview

Android Infrastructure Overview

Alexey Buzdin

April 24, 2013
Tweet

More Decks by Alexey Buzdin

Other Decks in Programming

Transcript

  1. Overview of Android Infrastructure Alexey Buzdin March 2013

  2. @AlexeyBuzdin! ! ! [email protected]! ! ! LArchaon!

  3. Everyone needs an app....

  4. we need an app too!

  5. Simple CRUD app

  6. Requirement:! ! Support as many android devices as you can!

    (phones + tablets)
  7. 4.0 4.1–4.2 3.0 2.3 2.2 2.1 Google data, March 2013

  8. None
  9. Ain't that good for a developer

  10. None
  11. None
  12. None
  13. Is there is someone who could solve this?

  14. nope

  15. Ease our pain?

  16. maybe

  17. None
  18. None
  19. Layers Presentation ! Application logic ! Domain Presentation ! Application

    logic ! Domain
  20. Presentation ! Application logic ! Domain Presentation ! Application logic

    ! Domain
  21. Spot the problem

  22. Missing in Android 2.2 • ActionBar! • Fragments (used for

    both tablets and phone support)
  23. Solution?

  24. Compatibility libraries Android Support library! ActionBarSherlock! etc

  25. Support Library http://developer.android.com/tools/extras/ support-library.html ! Fragments! Async Stuff! Experimental stuff

  26. Fragments

  27. Example

  28. ActionBar

  29. ActionBarSherlock http://actionbarsherlock.com/

  30. Refreshing list

  31. Pull to Refresh https://github.com/chrisbanes/ Android-PullToRefresh

  32. Presentation ! Application logic ! Domain Presentation ! Application logic

    ! Domain
  33. Android Runtime On Android you develop in Java ... but

    Android does not run Java bytecode !
  34. DalvikVM Dalvik Virtual Machine − Custom VM optimized for mobile

    devices − Register-based JVM − More efficient and compact − Use memory efficiently − Dalvik Executable Code (.dex) • 30% fewer instructions • 35% fewer code units • 35% more bytes − Trace JIT compiler (since 2.2)
  35. !35 Android Runtime Android Java = Java language + Dalvik

    + Apache Harmony Android Java API = Java SE – AWT/Swing + Android API Sun-Java = Java language + JVM + JDK
  36. App lifecycle

  37. Activity public class MyActivity extends Activity { ! @Override public

    void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } ! }
  38. None
  39. Activity public class MyActivity extends Activity { ! @Override public

    void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } ! }
  40. Resources

  41. Activity public class MyActivity extends Activity { ! @Override public

    void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } ! }
  42. Context • Context of current state of the application/object

  43. Context • Context of current state of the application/object! •

    Context is a handle to the system it provides services like ! − resolving resources ! − obtaining access to databases and preferences
  44. Important any resource taken from context will live as long

    as Context does
  45. Context problem public class MyActivity extends Activity { ! @Override

    public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); String appName = getString(R.string.appName); } ! }
  46. Passing Context public class MyStringProvider { ! Context context; !

    public MyStringProvider(Context context) { this.context = context; } ! public String getString(){ return context.getString(R.string.app_name); } ! }
  47. Passing Context

  48. Context problem public class MyActivity extends Activity { ! @Override

    public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); String appName = getString(R.string.appName); } ! } Presentation ! Application logic ! Domain Presentation ! Application logic ! Domain
  49. Injection libraries Dependency Injection! • RoboGuice! • Dagger

  50. RoboGuice • Based on Google Guice! • Lightweight! • Multifunctional

    (has resource injection)
  51. RoboGuice public class MyActivity extends RoboActivity { ! @Inject MyStringProvider

    stringProvider; ! @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); ! ((TextView) findViewById(R.id.textView)) .setText(stringProvider.getString()); } ! }
  52. RoboGuice public class MyStringProvider { ! Context context; ! @Inject

    public MyStringProvider(Context context) { this.context = context; } ! public String getString(){ return context.getString(R.string.app_name); } }
  53. Notable fact

  54. Minimal context injection public class MyActivity extends RoboActivity { !

    int i; ! @Inject MyStringProvider stringProvider; ! @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); ! i = 1; ((TextView) findViewById(R.id.textView)) .setText(stringProvider.getString()); } ! }
  55. RoboGuice public class MyStringProvider { ! Context context; ! @Inject

    public MyStringProvider(Context context) { this.context = context; } ! public String getString(){ return context.getString(R.string.app_name) + ((MyActivity)context).i; } }
  56. Dagger public class DaggerActivity extends DaggerBaseActivity { ! @Inject DaggerStringProvider

    stringProvider; ! @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); ! ((TextView) findViewById(R.id.textView)) .setText(stringProvider.getString()); } ! }
  57. Dagger public class DaggerBaseActivity extends Activity { ! @Inject Bus

    bus; ! @Override protected void onCreate(Bundle state) { super.onCreate(state); ! DaggerApplication.inject(this); } ! @Override protected void onResume() { super.onResume(); bus.register(this); } ! @Override protected void onPause() { super.onPause(); bus.unregister(this); } }
  58. Dagger public class DaggerApplication extends Application { ! private static

    ObjectGraph objectGraph; ! @Override public void onCreate() { super.onCreate(); ! objectGraph = ObjectGraph.create(new DaggerModule(this)); } ! public static <T> void inject(T instance) { if(objectGraph != null) objectGraph.inject(instance); } }
  59. @Module( entryPoints = { DaggerApplication.class, DaggerActivity.class} ) public class DaggerModule

    { private final Context appContext; ! public DaggerModule(Context appContext) { this.appContext = appContext.getApplicationContext(); } ! @Provides @Singleton Bus provideBus() { return new Bus(); } ! @Provides Context provideContext() { return appContext; } ! }
  60. Summary Dagger ! • More customizable! • Compile time injection!

    • Easy to use with other libraries! • Requires more code! ! RoboGuice! • Simpler! • Runtime injection! • Out of Box functionality
  61. Problem with views

  62. None
  63. None
  64. Other “Injection” libraries Resource and View “Injection”! • RoboGuice! •

    ButterKnife! • AndroidAnnotations
  65. RoboGuice Views Injection public class RoboGuiceActivity extends RoboActivity { !

    ! @Inject RoboGuiceStringProvider stringProvider; @InjectView(R.id.textView) TextView textView; ! @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); ! textView.setText(stringProvider.getString()); } ! }
  66. Butterknife public class DaggerActivity extends DaggerBaseActivity {! ! @Inject DaggerStringProvider

    stringProvider;! @InjectView(R.id.textView) TextView textView;! ! @Override! public void onCreate(Bundle savedInstanceState) {! super.onCreate(savedInstanceState);! setContentView(R.layout.main);! Views.inject(this);! ! textView.setText(stringProvider.getString());! }! ! }
  67. AndroidAnnotations @EActivity(R.layout.translate) // Sets content view to R.layout.translate! public class

    TranslateActivity extends Activity {! @ViewById // Injects R.id.textInput! EditText textInput;! @ViewById(R.id.myTextView) // Injects R.id.myTextView! TextView result;! @AnimationRes // Injects android.R.anim.fade_in! Animation fadeIn;! @Click // When R.id.doTranslate button is clicked ! void doTranslate() {! translateInBackground(textInput.getText().toString());! }! @Background // Executed in a background thread! void translateInBackground(String textToTranslate) {! String translatedText = callGoogleTranslate(textToTranslate);! showResult(translatedText);! }! ! @UiThread // Executed in the ui thread! void showResult(String translatedText) {! result.setText(translatedText);! result.startAnimation(fadeIn);! } ! }
  68. Presentation ! Application logic ! Domain Presentation ! Application logic

    ! Domain
  69. Data Source Android has built in SQLite

  70. Data Source ... but lacks ORM! ! Alternatives:! − GreenDAO!

    − ORMLite
  71. ORMLite @DatabaseTable(tableName = "accounts") public class Account { @DatabaseField(id =

    true) private String name; @DatabaseField(canBeNull = false) private String password; Account() { // all persisted classes must define a no-arg constructor with at least package visibility } }
  72. // you get the SQLiteOpenHelper from your Android Activity ConnectionSource

    connectionSource = new AndroidConnectionSource(sqliteOpenHelper); ! // instantiate the DAO to handle Account with String id Dao<Account,String> accountDao = BaseDaoImpl.createDao(connectionSource, Account.class); ! TableUtils.createTable(connectionSource, Account.class); ! String name = "Jim Smith"; Account account = new Account(name, "_secret"); accountDao.create(account) ! Account account2 = accountDao.queryForId(name); connectionSource.close(); ORMLite
  73. Testing

  74. Testing • DVM or JVM! • Automation or Unit Tests

  75. DVM • Requires a separate Test Project! • android.test or

    Robotium
  76. Android.test public class SimpleActivityTestStandard extends! ActivityUnitTestCase<SimpleActivity> {! public SimpleActivityTestStandard() {!

    super(SimpleActivity.class);! }! ! public void setUp() throws Exception {! startActivity(new Intent(getInstrumentation().getTargetContext(),! SimpleActivity.class), null, null);! }! ! ! public void testLayout() {! SimpleActivity activity = getActivity();! assertNotNull(activity.findViewById(R.id.button1));! Button view = (Button) activity! .findViewById(com.example.test.target.R.id.button1);! assertEquals("My Button 1", view.getText());! }! }
  77. Robotium ! public void testPreferenceIsSaved() throws Exception {! ! !

    Solo solo = new Solo(getInstrumentation(), getActivity());! solo.sendKey(Solo.MENU);! solo.clickOnText("More");! solo.clickOnText("Preferences");! solo.clickOnText("Edit File Extensions");! assertTrue(solo.searchText("rtf"));! ! solo.clickOnText("txt");! solo.clearEditText(2);! solo.enterText(2, "robotium");! solo.clickOnButton("Save");! solo.goBack();! solo.clickOnText("Edit File Extensions");! ! assertTrue(solo.searchText("application/robotium")! ! ! solo.finishOpenedActivities();! );!
  78. JVM public class RoboGuiceActivityTest { ! @Test public void shouldHaveISet()

    throws Exception { RoboGuiceActivity activity = new RoboGuiceActivity(); assertThat(activity.getI(), equalTo(1)); } }
  79. JVM public class RoboGuiceActivityTest { ! @Test public void shouldHaveISet()

    throws Exception { RoboGuiceActivity activity = new RoboGuiceActivity(); assertThat(activity.getI(), equalTo(1)); } }
  80. None
  81. We have Mockito! 
 lets mock something 
 in our

    Activity ...
  82. Activity source code

  83. Robolectric to the rescue Allows you to run ! you

    android code ! on JVM
  84. Robolectric @RunWith(RobolectricRoboTestRunner.class) public class RoboGuiceActivityTest { ! @Test public void

    shouldHaveISet() throws Exception { RoboGuiceActivity activity = new RoboGuiceActivity(); activity.onCreate(null); assertThat(activity.getI(), equalTo(1)); } }
  85. Robolectric + Mockito

  86. Testing • DVM or JVM! • Automation or Unit Tests!

    • Robotium or Robolectric! • Or both
  87. Conclusion

  88. More libraries?

  89. More libraries

  90. Solution?

  91. Android Bootstrap • Fragments,Fragment Pager! • android-maven-plugin, Dagger! • ActionBarSherlock

    ! • ViewPagerIndicator! • http-request, GSON ! • Robotium http://www.androidbootstrap.com/
  92. Build Systems • Gradle • Maven ! https://github.com/LArchaon/ android_mvn_template/

  93. Q&A