Overview of Android Infrastructure

4,126 views
3,984 views

Published on

0 Comments
5 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
4,126
On SlideShare
0
From Embeds
0
Number of Embeds
7
Actions
Shares
0
Downloads
62
Comments
0
Likes
5
Embeds 0
No embeds

No notes for slide

Overview of Android Infrastructure

  1. 1. Overview of Android Infrastructure Alexey Buzdin
  2. 2. @AlexeyBuzdinalex.buzdin@gmail.com LArchaon
  3. 3. Everyone needs an app....
  4. 4. We need an app too!
  5. 5. simple CRUD app
  6. 6. Requirement:Support as many android devices as you can (including tablets)
  7. 7. 4.1–4.24.0 2.13.0 2.22.3 Google data, March 2013
  8. 8. Aint that good for a developer
  9. 9. Is there is someone who could help us?
  10. 10. nope
  11. 11. Ease our pain
  12. 12. maybe
  13. 13. Layers PresentationApplication logic Domain
  14. 14. PresentationApplication logic Domain
  15. 15. But Whers the problem?
  16. 16. Missing in Android 2.2● ActionBar● Support for tablets● Decent ListView support for server communication
  17. 17. Solution?
  18. 18. Compatability librariesAndroid Support libraryActionBarSherlocketc
  19. 19. Support Libraryhttp://developer.android.com/tools/extras/support-library.html Fragments Async Stuff Experimental stuff
  20. 20. Fragments
  21. 21. Example
  22. 22. ActionBar
  23. 23. ActionBarSherlock http://actionbarsherlock.com/
  24. 24. Refreshing list
  25. 25. Pull to Refresh https://github.com/chrisbanes/Andro id-PullToRefresh
  26. 26. PresentationApplication logic Domain
  27. 27. Android RuntimeOn Android you develop in Java ... but Android does not run Java Bytecode !
  28. 28. DalvikVMDalvik 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)
  29. 29. Android RuntimeAndroid Java = Java language + Dalvik + Apache HarmonyAndroid Java API = Java SE – AWT/Swing + Android APISun-Java = Java language + JVM + JDK 36
  30. 30. App lifecycle
  31. 31. Activitypublic class MyActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); }}
  32. 32. Activitypublic class MyActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); }}
  33. 33. Resources
  34. 34. Activitypublic class MyActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); }}
  35. 35. Context● Context of current state of the application/object
  36. 36. 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
  37. 37. Importantany resource taken from context will leave as long as Context does
  38. 38. Context problempublic class MyActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); String appName = getString(R.string.appName); }}
  39. 39. Passing Contextpublic class MyStringProvider { Context context; public MyStringProvider(Context context) { this.context = context; } public String getString(){ return context.getString(R.string.app_name); }}
  40. 40. Passing Context
  41. 41. Context problempublic 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
  42. 42. Injection libraries Dependency Injection● RoboGuice● Dagger
  43. 43. RoboGuice● Based on Google Guice● Lightweight● Multifunctional (has resource injection)
  44. 44. RoboGuicepublic 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()); }}
  45. 45. RoboGuicepublic class MyStringProvider { Context context; @Inject public MyStringProvider(Context context) { this.context = context; } public String getString(){ return context.getString(R.string.app_name); }}
  46. 46. Notable fact
  47. 47. Optimezed context injectionpublic 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()); }}
  48. 48. RoboGuicepublic 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; }}
  49. 49. Daggerpublic 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()); }}
  50. 50. Daggerpublic 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); }}
  51. 51. Daggerpublic 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); }}
  52. 52. @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; }}
  53. 53. Summary Dagger● More customizable● Easy communicates with other libraries● Requires more code RoboGuice● Simpler● Out of Box functionality
  54. 54. Problem with views
  55. 55. Other “Injection” libraries Resource and View “Injection”● RoboGuice● ButterKnife● AndroidAnnotations
  56. 56. RoboGuice Views Injectionpublic 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()); }}
  57. 57. Butterknifepublic 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()); }}
  58. 58. AndroidAnnotations@EActivity(R.layout.translate) // Sets content view to R.layout.translatepublic 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); }}
  59. 59. PresentationApplication logic Domain
  60. 60. Data SourceAndroid has built in SQLite
  61. 61. Data Source... but lacks ORMAlternatives:– GreenDAO– ORMLite
  62. 62. 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 packagevisibility }}
  63. 63. ORMLite// you get the SQLiteOpenHelper from your Android ActivityConnectionSource connectionSource = new AndroidConnectionSource(sqliteOpenHelper);// instantiate the DAO to handle Account with String idDao<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();
  64. 64. Testing
  65. 65. Testing● DVM or JVM● Automation or Unit Tests
  66. 66. DVM● Requires a separate Test Project● android.test or Robotium
  67. 67. Android.testpublic class SimpleActivityTestStandard extends ActivityUnitTestCase<SimpleActivity> { public SimpleActivityTestStandard() { super(SimpleActivity.class); } public void setUp() throws Exception { startActivity(newIntent(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()); }}
  68. 68.   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(););               
  69. 69. JVMpublic class RoboGuiceActivityTest { @Test public void shouldHaveISet() throws Exception { RoboGuiceActivity activity = new RoboGuiceActivity(); assertThat(activity.getI(), equalTo(1)); }}
  70. 70. JVMpublic class RoboGuiceActivityTest { @Test public void shouldHaveISet() throws Exception { RoboGuiceActivity activity = new RoboGuiceActivity(); assertThat(activity.getI(), equalTo(1)); }}
  71. 71. We have Mockito!lets mock something in our Activity ...
  72. 72. Activity source code
  73. 73. Robolectric to the rescue Allows you to run you android code on JVM
  74. 74. 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)); }}
  75. 75. Robolectric + Mockito
  76. 76. Testing● DVM or JVM● Automation or Unit Tests● Robotium or Robolectric● Or both
  77. 77. Conclusion
  78. 78. More libraries?
  79. 79. More libraries
  80. 80. Solution?
  81. 81. Android Bootstrap● Fragments,Fragment Pager● android-maven-plugin, Dagger● ActionBarSherlock● ViewPagerIndicator● http-request, GSON● Robotium http://www.androidbootstrap.com/
  82. 82. or customs scripts
  83. 83. Build Systems● Gradle● Maven https://github.com/LArchaon/android _mvn_template/
  84. 84. Questions?

×