Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

about.me/wuman 2

Slide 3

Slide 3 text

Overview • Why use open source? • Popular open source Android libraries • Why open source? • How to open source • Conclusion 3

Slide 4

Slide 4 text

Why use open source? 4

Slide 5

Slide 5 text

Better Quality • Developed by many passionate developers • Innovation and enhancements over time • Improvements and bug fixes by more people • Closest to user needs 5

Slide 6

Slide 6 text

Freedom • Make custom changes to tailor to own needs • Good open source software usually adheres to open standards and promotes interoperability 6

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

Not Possible Otherwise • It is much harder to develop an Android app without using open source software • Platform compatibility • UI compatibility 8

Slide 9

Slide 9 text

Android app development is NOT easy! 9

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

UI Requirements for Featured Apps • Follow Android Design guidelines • Navigation • Action Bar • Use common UI patterns and icons 11

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

Theme Incompatibility • There is not a common cross-platform default theme for developers to derive from. 13

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

Popular Open Source Libraries 16

Slide 17

Slide 17 text

UI and Compatibility 17

Slide 18

Slide 18 text

ActionBarSherlock http://actionbarsherlock.com/ 18

Slide 19

Slide 19 text

Action Bar General Layout • App icon and “up” affordance • View switch control • Action buttons • Action overflow 19

Slide 20

Slide 20 text

Split Action Bar • Main action bar • Top bar via tabs or spinner • Bottom bar with action buttons and overflow 20

Slide 21

Slide 21 text

Contextual Action Bars 21

Slide 22

Slide 22 text

HoloEverywhere https://github.com/ChristopheVersieux/HoloEverywhere • Back ports the Holo themes from Jelly Bean to Eclair and above 22

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

UnifiedPreference https://github.com/saik0/UnifiedPreference 24

Slide 25

Slide 25 text

Android Support Package • Back ports multi-pane Fragment support from Honeycomb to Donut 25

Slide 26

Slide 26 text

Android Support Package • Includes ViewPager, PagerTitleStrip, PagerTabStrip implementations 26

Slide 27

Slide 27 text

Android Support Package • Back ports all Notification features from Jelly Bean to Donut 27

Slide 28

Slide 28 text

Android Support Package • Back ports asynchronous background Loader support from Honeycomb to Donut • Includes implementation for a memory-based LruCache 28

Slide 29

Slide 29 text

Android-MenuDrawer https://github.com/SimonVT/android-menudrawer 29

Slide 30

Slide 30 text

Android-PullToRefresh https://github.com/chrisbanes/Android-PullToRefresh 30

Slide 31

Slide 31 text

Polaris https://github.com/cyrilmottier/Polaris 31

Slide 32

Slide 32 text

Crouton https://github.com/keyboardsurfer/Crouton 32

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

Caching and Networking 34

Slide 35

Slide 35 text

DiskLruCache • Back ports the DiskLruCache from Ice Cream Sandwich to all versions of Android https://github.com/JakeWharton/DiskLruCache 35

Slide 36

Slide 36 text

TwoLevelLruCache • A two-level LRU cache composed of • first level memory-based LruCache • second level disk-based DiskLruCache http://wuman.github.com/TwoLevelLruCache/ 36

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

Concurrency and Communication 40

Slide 41

Slide 41 text

Tape • Provides a persistent task queue http://square.github.com/tape/ TaskQueue add() peek() remove() Client UI Server Service UploadTask UploadTask 41

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

Data Representation and Processing 43

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

Jackson JSON Processor • Streaming JSON parser and serializer • Supposedly faster than the built-in ones http://wiki.fasterxml.com/JacksonHome 45

Slide 46

Slide 46 text

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

Slide 47

Slide 47 text

jOOX - Java Object Oriented XML • XML manipulative parser with selector syntax • XML document creation https://github.com/jOOQ/jOOX 47

Slide 48

Slide 48 text

JSoup • HTML parser for Java using jQuery-like selector syntax • Manipulates HTML elements, attributes and text • Prettifies HTML http://jsoup.org/ 48

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

Google Guava • Many utilities to make Java development easier http://code.google.com/p/guava-libraries/ 50

Slide 51

Slide 51 text

Dependency Injection 51

Slide 52

Slide 52 text

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

Slide 53

Slide 53 text

RoboGuice • Runtime injection of Android views, system services, resources, POJO, etc. http://code.google.com/p/roboguice/ 53

Slide 54

Slide 54 text

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

Slide 55

Slide 55 text

Testing 55

Slide 56

Slide 56 text

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

Slide 57

Slide 57 text

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

Slide 58

Slide 58 text

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

Slide 59

Slide 59 text

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

Slide 60

Slide 60 text

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

Slide 61

Slide 61 text

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

Slide 62

Slide 62 text

User Feedback 62

Slide 63

Slide 63 text

ACRA • Sends a detailed bug or crash report to Google Docs http://acra.ch/ 63

Slide 64

Slide 64 text

BugSense/Crittercism • Collects bug and crash reports • Generates analytics for crash reports • Supports fix versioning and notifications http://www.bugsense.com/docs/android 64

Slide 65

Slide 65 text

Google Analytics for Android • Collect user engagement data and generate real time analytics • Demo https://developers.google.com/analytics/devguides/collection/android/v2/ 65

Slide 66

Slide 66 text

Bootstrap Project Generator 66

Slide 67

Slide 67 text

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

Slide 68

Slide 68 text

AndroidKickstartR • Includes a full working implementation of • Android support package • android-maven-plugin • AndroidAnnotations • ActionBarSherlock • NineOldAndroids • ACRA http://androidkickstartr.com/ 68

Slide 69

Slide 69 text

Tools 69

Slide 70

Slide 70 text

Android Asset Studio • Demo http://android-ui-utils.googlecode.com/hg/asset-studio/dist/index.html 70

Slide 71

Slide 71 text

Subtle Patterns • Collection of free tilable textured patterns • Demo http://subtlepatterns.com/ 71

Slide 72

Slide 72 text

Charles • HTTP proxy that enables developers to view all HTTP/HTTPS traffic between the device and the Internet http://www.charlesproxy.com/ 72

Slide 73

Slide 73 text

Others 73

Slide 74

Slide 74 text

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

Slide 75

Slide 75 text

Why open source? 75

Slide 76

Slide 76 text

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

Slide 77

Slide 77 text

Reciprocity • A way to give back to the community • Feels good 77

Slide 78

Slide 78 text

Portfolio Buildup • GitHub, not LinkedIn 78

Slide 79

Slide 79 text

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

Slide 80

Slide 80 text

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

Slide 81

Slide 81 text

How to Open Source 81

Slide 82

Slide 82 text

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

Slide 83

Slide 83 text

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

Slide 84

Slide 84 text

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

Slide 85

Slide 85 text

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

Slide 86

Slide 86 text

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

Slide 87

Slide 87 text

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

Slide 88

Slide 88 text

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

Slide 89

Slide 89 text

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

Slide 90

Slide 90 text

Inclusion of Examples • Add at least one or more working examples. • Separate examples to showcase a specific aspect of the library. 90

Slide 91

Slide 91 text

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

Slide 92

Slide 92 text

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

Slide 93

Slide 93 text

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

Slide 94

Slide 94 text

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

Slide 95

Slide 95 text

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

Slide 96

Slide 96 text

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

Slide 97

Slide 97 text

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

Slide 98

Slide 98 text

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/ DocumentUp.document({ repo:  "wuman/AndroidImageLoader", name:  "AndroidImageLoader", twitter:  ["wuman"], issues:  true, travis:  true, google_analytics:  "UA-­‐4156099-­‐13" }); 98

Slide 99

Slide 99 text

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

Slide 100

Slide 100 text

Mailing List • Setup a Google Groups mailing list for the project so that people can have a place for discussion. 100

Slide 101

Slide 101 text

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

Slide 102

Slide 102 text

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

Slide 103

Slide 103 text

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

Slide 104

Slide 104 text

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

Slide 105

Slide 105 text

Conclusion 105

Slide 106

Slide 106 text

106

Slide 107

Slide 107 text

“Only the children know what they are looking for.” The Little Prince 106

Slide 108

Slide 108 text

Thank you 107

Slide 109

Slide 109 text

Q & A 108