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

A Deep Dive into Open Source Android Development

David Wu
December 07, 2012

A Deep Dive into Open Source Android Development

The increasing popularity of the Android platform over the past two years has encouraged many talented developers to contribute. Developers no longer need to invent their own wheels from scratch. Instead, many open source tools and libraries are becoming available for Android developers. In this talk we will take a deep dive into Android programming and how developers can leverage open source tools to bootstrap their Android apps. We will also talk about how developers can contribute back to the open source community.

David Wu

December 07, 2012
Tweet

More Decks by David Wu

Other Decks in Programming

Transcript

  1. A Deep Dive into Open Source Android Development David Wu

    @wuman blog.wu-man.com Taipei Google Technology User Group (2013/01/02) Taipei Open Source Software User Group (2012/12/18) ݩஐେላࢿ޻ላܥ ։์ݯᛰԙߦಈऴ୺೭ᚙలߨ࠲ (2012/12/07) 1
  2. Overview • Why use open source? • Popular open source

    Android libraries • Why open source? • How to open source • Conclusion 3
  3. Better Quality • Developed by many passionate developers • Innovation

    and enhancements over time • Improvements and bug fixes by more people • Closest to user needs 5
  4. Freedom • Make custom changes to tailor to own needs

    • Good open source software usually adheres to open standards and promotes interoperability 6
  5. Learn from the Masters • Open source developers are usually

    good at what they do • The fastest way to improve is to learn from reading their code • Discussions are usually carried out in the open via mailing lists 7
  6. Not Possible Otherwise • It is much harder to develop

    an Android app without using open source software • Platform compatibility • UI compatibility 8
  7. Apps targeting the widest audience need to care about platform

    compatibility Jelly Bean Ice Cream Sandwich Honeycomb Gingerbread Froyo Eclair & older Version Codename API Distribution 1.5 Cupcake 3 0.1% 1.6 Donut 4 0.3% 2.1 Eclair 7 2.7% 2.2 Froyo 8 10.3% 2.3 - 2.3.2 Gingerbread 9 0.2% 2.3.3 - 2.3.7 Gingerbread 10 50.6% 3.1 Honeycomb 12 0.4% 3.2 Honeycomb 13 1.2% 4.0.3 - 4.0.4 Ice Cream Sandwich 15 27.5% 4.1 Jelly Bean 16 5.9% 4.2 Jelly Bean 17 0.8% 10
  8. UI Requirements for Featured Apps • Follow Android Design guidelines

    • Navigation • Action Bar • Use common UI patterns and icons 11
  9. Action Bar Incompatibility • Before 3.0, there was no common

    pattern or API for in-app navigation. • Action Bar API and pattern guidelines (tablet-only) are introduced in ICS. • Additional API changes for the phone are introduced in Jelly Bean. 12
  10. Common UI Pattern Implementations • Some common UI patterns are

    not provided as part of the Android framework. • Pull-to-refresh ListView • Sliding Drawer Menu (ViewDeck) 14
  11. Common Tools and Usage Patterns • Some common tools and

    usage patterns are not provided as part of the Android framework. • LRU cache that persists to disk • Image loading with cache support • Logging and user feedback support 15
  12. Action Bar General Layout • App icon and “up” affordance

    • View switch control • Action buttons • Action overflow 19
  13. Split Action Bar • Main action bar • Top bar

    via tabs or spinner • Bottom bar with action buttons and overflow 20
  14. NineOldAndroids • Back ports the android.animation.* API from Honeycomb to

    all previous platforms • Drawing vs. View properties http://nineoldandroids.com/ ObjectAnimator.ofFloat(myObject, "translationY", -myObject.getHeight()).start(); 23
  15. Android Support Package • Back ports asynchronous background Loader support

    from Honeycomb to Donut • Includes implementation for a memory-based LruCache 28
  16. Android-Query http://code.google.com/p/android-query/ • Enables easier UI manipulation via method chaining

    AQuery aq = new AQuery(view); aq.id(R.id.icon) .image(R.drawable.icon) .visible() .clicked(this, "someMethod"); aq.id(R.id.name) .text(content.getPname()); aq.id(R.id.time) .text(FormatUtility.relativeTime( System.currentTimeMillis(), content.getCreate())) .visible(); aq.id(R.id.desc) .text(content.getDesc()) .visible(); 33
  17. DiskLruCache • Back ports the DiskLruCache from Ice Cream Sandwich

    to all versions of Android https://github.com/JakeWharton/DiskLruCache 35
  18. TwoLevelLruCache • A two-level LRU cache composed of • first

    level memory-based LruCache • second level disk-based DiskLruCache http://wuman.github.com/TwoLevelLruCache/ 36
  19. AndroidImageLoader • Asynchronous image loading • Images are downloaded and

    saved to TwoLevelLruCache via a pool of background threads • Supports Bitmap transformations http://wuman.github.com/AndroidImageLoader/ 37
  20. HttpResponseCache • Back ports the persistent HttpResonseCache from Ice Cream

    Sandwich to all versions of Android • Provides transparent and automatic persistent caching of HTTP and HTTPS requests that use the HttpUrlConnection class https://github.com/candrews/HttpResponseCache 38
  21. HTTP-Request • Provides a simpler and easier interface to HttpURLConnection

    • Uses method chaining https://github.com/kevinsawicki/http-request HttpRequest.get("http://google.com").receive(System.out); 39
  22. Tape • Provides a persistent task queue http://square.github.com/tape/ TaskQueue add()

    peek() remove() Client UI Server Service UploadTask UploadTask 41
  23. Otto • An event bus forked from EventBus of Google

    Guava targeting the Android platform http://square.github.com/otto/ Bus Fragment Fragment Fragment Fragment Service Activity Publish Subscribe 42
  24. GSON • POJO to JSON bi-directional conversion • Built-in serializers

    and deserializers for primitive data types • Supports extensions for complex objects http://code.google.com/p/google-gson/ 44
  25. Jackson JSON Processor • Streaming JSON parser and serializer •

    Supposedly faster than the built-in ones http://wiki.fasterxml.com/JacksonHome 45
  26. Json-Path • XPath- and jQuery-like selector for JSON { "store":

    { "book": [ { "category": "reference", "author": "Nigel Rees", "title": "Sayings of the Century", "price": 8.95 }, { "category": "fianceection", "author": "Evelyn Waugh", "title": "Sword of Honour", "price": 12.99, "isbn": "0-553-21311-3" } ], "bicycle": { "color": "red", "price": 19.95 } } } String author = JsonPath.read(json, "$.store.book[1].author"); http://code.google.com/p/json-path/ 46
  27. jOOX - Java Object Oriented XML • XML manipulative parser

    with selector syntax • XML document creation https://github.com/jOOQ/jOOX 47
  28. JSoup • HTML parser for Java using jQuery-like selector syntax

    • Manipulates HTML elements, attributes and text • Prettifies HTML http://jsoup.org/ 48
  29. OrmLite • ORM library that persists POJO to SQLite databases

    http://ormlite.com/ public class SimpleData { ! @DatabaseField(generatedId = true) ! int id; ! @DatabaseField(index = true) ! String string; ! @DatabaseField ! long millis; ! @DatabaseField ! Date date; ! @DatabaseField ! boolean even; ! SimpleData() { ! ! // needed by ormlite ! } ! public SimpleData(long millis) { ! ! this.date = new Date(millis); ! ! this.string = (millis % 1000) + "ms"; ! ! this.millis = millis; ! ! this.even = ((millis % 2) == 0); ! } } 49
  30. Google Guava • Many utilities to make Java development easier

    http://code.google.com/p/guava-libraries/ 50
  31. AndroidAnnotations • Runtime injection of Android views, extras, system services,

    resources, etc. • Method annotation to indicate which thread to run in • Method annotation to bind event listeners to events http://androidannotations.org/ 52
  32. RoboGuice • Runtime injection of Android views, system services, resources,

    POJO, etc. http://code.google.com/p/roboguice/ 53
  33. Dagger • Compile-time dependency injection (binding validation) for Android •

    Not as feature-rich as other dependency injection frameworks but much faster • API very similar to Google Guice http://square.github.com/dagger/ † 54
  34. Android Test Framework • Built-in Android Test Project support •

    Use AndroidTestCase to test non-visual components • Use Instrumentation to control visual parts of an application • Command line monkey tool to send random events to device 56
  35. Robotium • Black-box testing framework for Android • Improved readability

    of test cases compared to standard Instrumentation tests • Handles multiple Android activities http://code.google.com/p/robotium/ 57
  36. Robotium http://www.vogella.com/articles/AndroidTesting/article.html // Check that we have the right activity

    solo.assertCurrentActivity("wrong activiy", SimpleActivity.class); // Click a button which will start a new Activity // Here we use the ID of the string to find the right button solo.clickOnButton(solo.getString(R.string.button1)); // Validate that the Activity is the correct one solo.assertCurrentActivity("wrong activiy", SimpleListActivity.class); // Open the menu solo.sendKey(Solo.MENU); solo.clickOnText("Preferences"); solo.clickOnText("User"); solo.clearEditText(0); Assert.assertTrue(solo.searchText("")); solo.enterText(0, "http//:www.vogella.com"); Assert.assertTrue(solo.searchText("http//:www.vogella.com")); solo.goBack(); 58
  37. Mochito • Android mocking framework • API makes mocking tests

    very readable http://code.google.com/p/mockito/ public void makePurchase(CreditCardManager creditCard) { if (creditCard.getCardType() == CREDIT_CARD_VISA) { creditCard.makePurchase(500); } } public void testMasterCardTransaction() { CreditCardManager creditCard = Mockito.mock(CreditCardManager.class); Mockito.when(creditCard.getCardType()) .thenReturn(CREDIT_CARD_MASTER); makePurchase(creditCard); Mockito.verify(creditCard).getCardType(); Mockito.verifyNoMoreInteractions(creditCard); } 59
  38. Robolectric • Allows JVM unit testing with the JUnit4 framework

    • Reduces testing time from minutes to seconds • Intercepts Android class loading and forward method bodies to shadow objects http://pivotal.github.com/robolectric/ 60
  39. Robolectric http://pivotal.github.com/robolectric/ // Test class for MyActivity @RunWith(RobolectricTestRunner.class) public class

    MyActivityTest { private Activity activity; private Button pressMeButton; private TextView results; @Before public void setUp() throws Exception { activity = new MyActivity(); activity.onCreate(null); pressMeButton = (Button) activity.findViewById(R.id.press_me_button); results = (TextView) activity.findViewById(R.id.results_text_view); } @Test public void shouldUpdateResultsWhenButtonIsClicked() throws Exception { pressMeButton.performClick(); String resultsText = results.getText().toString(); assertThat(resultsText, equalTo("Testing Android Rocks!")); } } 61
  40. ACRA • Sends a detailed bug or crash report to

    Google Docs http://acra.ch/ 63
  41. BugSense/Crittercism • Collects bug and crash reports • Generates analytics

    for crash reports • Supports fix versioning and notifications http://www.bugsense.com/docs/android 64
  42. Google Analytics for Android • Collect user engagement data and

    generate real time analytics • Demo https://developers.google.com/analytics/devguides/collection/android/v2/ 65
  43. Android Bootstrap • Includes a full working implementation of •

    Android support package • android-maven-plugin • RoboGuice • ActionBarSherlock • http-request • GSON • Robotium • API on Parse.com http://www.androidbootstrap.com/ 67
  44. AndroidKickstartR • Includes a full working implementation of • Android

    support package • android-maven-plugin • AndroidAnnotations • ActionBarSherlock • NineOldAndroids • ACRA http://androidkickstartr.com/ 68
  45. Charles • HTTP proxy that enables developers to view all

    HTTP/HTTPS traffic between the device and the Internet http://www.charlesproxy.com/ 72
  46. More Detailed Listing • App Dev Wiki http://appdevwiki.com/wiki/show/HomePage • The

    Ultimate Android Library http:// www.theultimateandroidlibrary.com/ • AppBrain Android Developer Tools http:// www.appbrain.com/stats/libraries/dev 74
  47. Better App Quality • Normally for various practical reasons we

    don’t open source the entire app • Open source useful components within the app into a library • More debugging for you • The process of open sourcing forces you to rethink your architecture critically 76
  48. Grow Faster • The more you engage in the open

    source community, the faster you learn and grow as a tech professional. • The process of open sourcing encompasses almost all areas of software development. 79
  49. Better World • What goes around comes around • The

    template for this Keynote presentation is derived from an open source project! https://github.com/JakeWharton/AndroidDesignKeynoteTheme 80
  50. Disclaimer What follows is based on the presentation “Effective Open

    Source” given by Jake Wharton and additionally, a more elaborate presentation based on my own experiences. https://github.com/JakeWharton/EffectiveOpenSource 82
  51. Component Identification • Identify the part of your app that

    can be extracted out as an isolated, reusable component. • The component should serve to do a focused task very well. 83
  52. Code Abstraction • Extract the component into a separate package

    or module and expose only via a small set of public API. • This is kind of like refactoring. The app should continue to work as expected and the module should be treated just like an external dependency. • Reiterate the refactoring step several times until • the exposed public API is minimal and clean • the client code has good readability 84
  53. Library Project Directory Structure • Make the module either an

    independent Java library project or an Android library project depending on whether Android resources are needed in the library. • Follow a common directory structure as defined in a maven archetype: • org.apache.maven.archetypes/maven- archetype-quickstart • de.akquinet.android.archetypes/android-release 85
  54. Android Library Project Directory Structure library/ Android Library project test/

    Android Test project samples/ Samples project (Android project) README Project’s readme LICENSE Project’s license NOTICE Notices and attributions required by libraries that the project depends on 86
  55. Java Library Project Directory Structure library/ Java library project library/src/main/java/

    Java library sources library/src/test/java/ Test sources samples/ Samples project (Android project) README Project’s readme LICENSE Project’s license NOTICE Notices and attributions required by libraries that the project depends on 87
  56. Include Tests • Good libraries are always bundled with tests.

    It gives people confidence and ensures quality. • Tests are never enough. Write as many as you can think of. • Ensure all the tests are passed. 88
  57. Code Quality and Style • Standardize code conventions. • Enforce

    coding style at compile time by using Checkstyle for Java. • This ensures that future patches have a consistent coding style. 89
  58. Inclusion of Examples • Add at least one or more

    working examples. • Separate examples to showcase a specific aspect of the library. 90
  59. Documentation • Make sure all exposed public APIs have documentation

    that follow the javadoc syntax. • Ensure that a javadoc jar is generated for each release. This is best achieved via the maven- javadoc-plugin. 91
  60. README • Write a README that follows the Markdown syntax.

    • It should include the following sections: • project description • how to obtain the library • snippets of quick start sample code • external dependencies • license information http://daringfireball.net/projects/markdown/syntax 92
  61. Git Ignore • Always include a .gitignore file to keep

    the source tree clean. There are many samples online. • In general exclude these files: • IDE-specific files (Eclipse.gitignore) • OS-specific files (OSX.gitignore) • Android outputs and binaries (Android.gitignore) • Java compiled classes and package files (Java.gitignore) https://github.com/github/gitignore 93
  62. Build Management Tool • Use a build management tool to

    help people painlessly build your code without needing to know much about the library. • Most Android people use Maven. • Write the configuration file that works with your build management tool. In the case of Maven it should be pom.xml. 94
  63. Maven • Install the latest com.jayway.maven.plugins.android.generation2/ android-maven-plugin. • The packaging

    for the library project should be either jar or apklib, depending on whether your library is a Java project or an Android Library project. • The packaging for the samples project should be apk. http://code.google.com/p/maven-android-plugin/ 95
  64. Build with Maven • Make sure the build management tool

    builds your project correctly. • For Maven, you should be able to run the following without errors: http://maven.apache.org/pom.html $  mvn  clean  install 96
  65. Continuous Integration • Setup continuous integration. The simplest open source

    service is Travis. Have your GitHub repository linked to Travis by activating a hook. • Write the configuration file .travis.yml. https://travis-ci.org/ language:  java                                                                                                                                                                                                                                                                                                                         notifications:    email:  false before_install:    -­‐  wget  http://dl.google.com/android/android-­‐sdk_r20.0.3-­‐linux.tgz    -­‐  tar  -­‐zxf  android-­‐sdk_r20.0.3-­‐linux.tgz    -­‐  export  ANDROID_HOME=~/builds/username/projectName/android-­‐sdk-­‐linux    -­‐  export  PATH=${PATH}:${ANDROID_HOME}/tools:${ANDROID_HOME}/platform-­‐tools    -­‐  android  list  sdk      -­‐  android  update  sdk  -­‐-­‐filter  1,2,3  -­‐-­‐no-­‐ui  -­‐-­‐force 97
  66. Site Setup • Setup a project web site. • If

    you’re lazy and wish to use just the GitHub README, then the best alternative is the DocumentUp service. • Configure Travis indicator and Google Analytics tracking for the web site. http://documentup.com/ <script  src="https://raw.github.com/jeromegn/DocumentUp/master/documentup.min.js"></script> <script> DocumentUp.document({ repo:  "wuman/AndroidImageLoader", name:  "AndroidImageLoader", twitter:  ["wuman"], issues:  true, travis:  true, google_analytics:  "UA-­‐4156099-­‐13" }); </script> 98
  67. Issue Management • GitHub has built-in issue management support, although

    many developers consider Google Code to be better for issue management. • Quick triage of issues 99
  68. Mailing List • Setup a Google Groups mailing list for

    the project so that people can have a place for discussion. 100
  69. Downloadable Published Packages • Always make the released packages (usually

    jars) available for download. Use the com.github.github/downloads-maven-plugin. • If your library has dependencies, it is best to release a separate jar with dependencies using the maven-assembly-plugin. https://github.com/github/maven-plugins 101
  70. Release to Sonatype and Maven Central • Sonatype provides an

    OSS repository hosting service for free. You can deploy snapshots and releases so that they are also synced periodically to Maven Central. • Follow their detailed guide. • In the end you should be able to deploy your project with: https://docs.sonatype.org/display/Repository/Sonatype+OSS+Maven+Repository+Usage+Guide $  mvn  clean  package  release:prepare $  mvn  release:perform 102
  71. Promote the Library • Write a blog post to talk

    about the motivations behind the project, technical explanations and sample code snippets. Also direct readers to the project page. • Publish your project everywhere: social networks, related communities, etc. • Encourage people to use and contribute. • Ask for feedback. 103
  72. Join the Android Community • Follow these smart people on

    Google+: • Googlers • Chet Haase, Dan Morrill, Dianne Hackborn, Jean-Baptiste Quéru, Jeff Sharkey, Kirill Grouchnikov, Matias Duarte, Patrick Dubroy, Reto Meier, Roman Nurik, Romain Guy, Tor Norbye, Xavier Ducrohet • Android Developers • Community • Bob Lee, Chris Banes, Cyril Mottier, David Wu (shameless plug), Eric Burke, Jake Wharton, Jesse Wilson, Lars Vogel, Steve Kondik 104
  73. 106