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. Android Runtime On Android you develop in Java ... but

    Android does not run Java bytecode !
  2. 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)
  3. !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
  4. Activity public class MyActivity extends Activity { ! @Override public

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

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

    void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } ! }
  7. 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
  8. 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); } ! }
  9. Passing Context public class MyStringProvider { ! Context context; !

    public MyStringProvider(Context context) { this.context = context; } ! public String getString(){ return context.getString(R.string.app_name); } ! }
  10. 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
  11. 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()); } ! }
  12. RoboGuice public class MyStringProvider { ! Context context; ! @Inject

    public MyStringProvider(Context context) { this.context = context; } ! public String getString(){ return context.getString(R.string.app_name); } }
  13. 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()); } ! }
  14. 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; } }
  15. 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()); } ! }
  16. 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); } }
  17. 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); } }
  18. @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; } ! }
  19. Summary Dagger ! • More customizable! • Compile time injection!

    • Easy to use with other libraries! • Requires more code! ! RoboGuice! • Simpler! • Runtime injection! • Out of Box functionality
  20. 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()); } ! }
  21. 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());! }! ! }
  22. 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);! } ! }
  23. 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 } }
  24. // 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
  25. 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());! }! }
  26. 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();! );!
  27. JVM public class RoboGuiceActivityTest { ! @Test public void shouldHaveISet()

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

    throws Exception { RoboGuiceActivity activity = new RoboGuiceActivity(); assertThat(activity.getI(), equalTo(1)); } }
  29. 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)); } }
  30. Testing • DVM or JVM! • Automation or Unit Tests!

    • Robotium or Robolectric! • Or both
  31. Android Bootstrap • Fragments,Fragment Pager! • android-maven-plugin, Dagger! • ActionBarSherlock

    ! • ViewPagerIndicator! • http-request, GSON ! • Robotium http://www.androidbootstrap.com/
  32. Q&A