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.
Automation: The Good, The Bad and The Ugly with DevOpsGuys - AppD Summit Europe
A Deep Dive into Open Source Android Development
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
5. Better Quality
• Developed by many passionate developers
• Innovation and enhancements over time
• Improvements and bug fixes by more people
• Closest to user needs
5
6. Freedom
• Make custom changes to tailor to own needs
• Good open source software usually adheres to
open standards and promotes interoperability
6
7. 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
8. Not Possible Otherwise
• It is much harder to develop an Android app
without using open source software
• Platform compatibility
• UI compatibility
8
10. Version Codename API Distribution
Eclair & older
1.5 Cupcake 3 0.1%
Jelly Bean
1.6 Donut 4 0.3% Froyo
2.1 Eclair 7 2.7%
2.2 Froyo 8 10.3%
Ice Cream Sandwich
2.3 - 2.3.2 9 0.2%
Gingerbread
2.3.3 - 2.3.7 10 50.6%
3.1 12 0.4%
Honeycomb
3.2 13 1.2%
Gingerbread
Honeycomb
Ice Cream
4.0.3 - 4.0.4 15 27.5%
Sandwich
4.1 16 5.9%
Jelly Bean
4.2 17 0.8%
Apps targeting the widest audience need to
care about platform compatibility
10
11. UI Requirements for Featured Apps
• Follow Android Design guidelines
• Navigation
• Action Bar
• Use common UI patterns and icons
11
12. 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
14. 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
15. 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
22. HoloEverywhere
• Back ports the Holo themes
from Jelly Bean to Eclair and
above
https://github.com/ChristopheVersieux/HoloEverywhere
22
23. NineOldAndroids
• Back ports the android.animation.* API from
Honeycomb to all previous platforms
• Drawing vs. View properties
ObjectAnimator.ofFloat(myObject, "translationY",
-myObject.getHeight()).start();
http://nineoldandroids.com/
23
28. Android Support Package
• Back ports asynchronous background Loader
support from Honeycomb to Donut
• Includes implementation for a memory-based
LruCache
28
35. DiskLruCache
• Back ports the DiskLruCache from Ice Cream
Sandwich to all versions of Android
https://github.com/JakeWharton/DiskLruCache
35
36. TwoLevelLruCache
• A two-level LRU cache
composed of
• first level memory-based
LruCache
• second level disk-based
DiskLruCache
http://wuman.github.com/TwoLevelLruCache/
36
37. 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
38. 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
39. HTTP-Request
• Provides a simpler and easier interface to
HttpURLConnection
• Uses method chaining
HttpRequest.get("http://google.com").receive(System.out);
https://github.com/kevinsawicki/http-request
39
41. Tape
• Provides a persistent task queue
Server
Client UI
TaskQueue peek()
remove()
add()
UploadTask UploadTask Service
http://square.github.com/tape/
41
42. Otto
• An event bus forked from EventBus of Google
Guava targeting the Android platform
Publish Subscribe
Fragment Fragment
Fragment Bus Fragment
Service Activity
http://square.github.com/otto/
42
44. 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
45. Jackson JSON Processor
• Streaming JSON parser and serializer
• Supposedly faster than the built-in ones
http://wiki.fasterxml.com/JacksonHome
45
47. jOOX - Java Object Oriented XML
• XML manipulative parser with selector syntax
• XML document creation
https://github.com/jOOQ/jOOX
47
48. JSoup
• HTML parser for Java using jQuery-like selector
syntax
• Manipulates HTML elements, attributes and text
• Prettifies HTML
http://jsoup.org/
48
49. OrmLite
• ORM library that persists POJO to SQLite
databases
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);
! }
}
http://ormlite.com/
49
50. Google Guava
• Many utilities to make Java development easier
http://code.google.com/p/guava-libraries/
50
52. 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
53. RoboGuice
• Runtime injection of Android views, system
services, resources, POJO, etc.
http://code.google.com/p/roboguice/
53
54. 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
56. 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
57. 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
58. Robotium
// 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();
http://www.vogella.com/articles/AndroidTesting/article.html
58
59. Mochito
• Android mocking framework
• API makes mocking tests very readable
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);
}
http://code.google.com/p/mockito/
59
60. 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
61. 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!"));
}
}
http://pivotal.github.com/robolectric/
61
63. ACRA
• Sends a detailed bug or crash report to Google
Docs
http://acra.ch/
63
64. BugSense/Crittercism
• Collects bug and crash reports
• Generates analytics for crash reports
• Supports fix versioning and notifications
http://www.bugsense.com/docs/android
64
65. Google Analytics for Android
• Collect user engagement data and generate real
time analytics
• Demo
https://developers.google.com/analytics/devguides/collection/android/v2/
65
67. 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
68. AndroidKickstartR
• Includes a full working implementation of
• Android support package
• android-maven-plugin
• AndroidAnnotations
• ActionBarSherlock
• NineOldAndroids
• ACRA
http://androidkickstartr.com/
68
76. 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
79. 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
80. 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
82. 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
83. 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
84. 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
85. 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
86. 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
Notices and attributions required by
NOTICE
libraries that the project depends on
86
87. 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
Notices and attributions required by
NOTICE
libraries that the project depends on
87
88. 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
89. 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
90. Inclusion of Examples
• Add at least one or more
working examples.
• Separate examples to
showcase a specific aspect
of the library.
90
91. 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
92. 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
93. 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
94. 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
95. 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
96. 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:
$
mvn
clean
install
http://maven.apache.org/pom.html
96
97. 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.
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
https://travis-ci.org/
97
98. 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.
<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>
http://documentup.com/
98
99. 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
100. Mailing List
• Setup a Google Groups mailing list for the project
so that people can have a place for discussion.
100
101. 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
102. 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:
$
mvn
clean
package
release:prepare
$
mvn
release:perform
https://docs.sonatype.org/display/Repository/Sonatype+OSS+Maven+Repository+Usage+Guide
102
103. 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
104. 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