Skip to content
mvestola edited this page Dec 11, 2012 · 18 revisions

Android system background

  • Linux kernel
  • No JVM but Dalvik VM

Android Stack.

Dalvik VM

Dalvik VM.

  • Slimmed down JVM for mobile (a subset of the Apache Harmony Java implementation)
  • Does not actually run Java code but uses ".dex" format (Dalvik Executable)
  • Build process (automated with e.g. maven):
  1. *.java -> *.class
  2. *.class -> classed.dex
  3. classes.dex + *.xml + images = app.apk (practically a zip file)
  4. Upload apk to Google Play (previously Google Market) or directly to phone

Complete build process: http://developer.android.com/tools/building/index.html

Dalvik VM vs JVM

  • Each app in Android runs in isolation in its own process and own Dalvik VM instance
  • Not all Java code works in Dalvik VM:
  • E.g. some mocking frameworks which depened on JVM classloaders
  • No runtime bytecode generation (affects e.g. Google Guice, AspectJ)
  • No Swing and AWT --> Some core Java SE classes missing (e.g. Point2D.Double)
  • Support for non-Java JVM languages limited (should work with Scala but not Groovy)

Java versions

Different Android API levels

See API levels and API level distribution

  • Some important classes are not supported in older API levels.
  • For example, Fragment class was added not until API level 11 (Android 3.0).
  • Use Android support library (single jar file) to support older devices

Two important concepts (defined in AndroidManifest.xml):

  • Target API level: You compile against this API level. Enables some newer features (e.g. if API level > 11, menu is hidden and actionbar is enabled in newer devices)
  • Minimum API level: You have ensured that the app works with this API level (e.g. disable features not supported). App won't install if its API level < Minimum API level.

Tools and documentation

Development tools

  • SDK Manager
  • Used to install Android APIs (basically a single jar file)
  • DDMS (Dalvik Debug Monitor Server)
  • Processes in emulators, file manager, kill apps, logs
  • AVD Manager (Android Virtual Devices)
  • Crating virtual devices (emulators)
  • ADB (Android Debug Bridge)
  • Communicating with emulator (e.g. install app, logs)
  • Hierarchy Viewer
  • View app's layout hierarchy
  • IDE support:
  • Eclipse ADT
  • IntelliJ IDEA 11
  • Graphical UI editors
  • Eclipse
  • IntelliJ IDEA 12
  • Droiddraw
  • Static code analysis tools
  • Android Lint, integrated to IntelliJ IDEA

Documentation

Some interesting articles / presentations:

Releasing app in Google Play

  • One-time $25 USD registration fee
  • Simply upload the apk file, add some screenshots and description
  • User reviews, crash reports (stacktraces), statistics

Testing

Android built-in junit testing sucks!

Andoid developer guide contains instructions for unit testing but DO NOT USE IT, because:

  • Need to create a separate project for tests
  • Unit tests run on emulator -> PAIN SLOW
  • Can't use Mockito or PowerMock (won't work with Dalvik VM)
  • Must use jUnit 3
  • ... many many other reasons

A better way

  • Run jUnit tests in standard JVM = very fast
  • Can now use normal Java testing tools: jUnit 4, Mockito, PowerMock...
  • Use Maven and place tests in standard test dir (src/test/java)
  • Avoid creating classes with dependencies to Android API
  • Separate domain code from android UI code
  • Otherwise you get "java.lang.RuntimeException: Stub!" in unit testing
  • Google API (android.jar) contains only stubs
  • Real android code can only be run on emulator or real device
  • 3rd party libraries help testing (Robolectric)

USB debugging on a real device

Much faster than running on an emulator. Should work on Windows, Linux and OS X: http://developer.android.com/tools/device.html

Helpful 3rd party libraries

Development how-to

Most important UI components

  • Activity
  • "Represents one screen." Uses Views and Fragments to create the UI and interact with user. Android app can have several Activities. Usually "one activity per screen".
  • Fragment
  • Introduced in Android 3.0. "Reusable activities". See example.
  • View
  • Widgets, e.g. button, text
  • ViewGroup
  • Layout managers (like Swing), e.g. RelativeLayoyt, LinearLayout, ListView

Other important components

  • Intent
  • Used to communicate between activities / applications
  • Service
  • Continually running long-lived task running in the background without UI
  • AsyncTask
  • Once-off time-consuming tasks that cannot be run of the UI thread.

Activity lifecycle

My Unicorn.

  • Usually one process per application (can be changed)
  • After onPause app can be killed by the system
  • After killed, returns to the same activity where user left the app

Supporting multiple devices

  • Use dp instead of px
  • Provide different layout XML files for different screen sizes (/res/layout-large)
  • Provide high and low resolution images: (/res/drawable-hdpi)

Conventions

Naming conventions

Some projects flawor the following guidelines:

  • Non-public, non-static field names start with m.
  • Static field names start with s.

So, e.g. member variables look like:

private String mUsername;

DO NOT DO THIS! It is just a C-style convention used in Android platform source code project

Package structure in non-Maven projects

Non-maven projects have slightly different directory structure: http://developer.android.com/tools/projects/index.html

Strange issues you might encounter in development:

  • Emulator is slow or freezes (quite normal)
  • Some common classes are missing in older APIs (e.g. ListPreference, String.isEmpty())
  • Forces you to use buggy 3rd party components if want to support older devices
  • 3rd party frameworks add functionality usually by forcing to extend some BaseActicity
  • Since Java has no multiple inheritance, combining multiple frameworks might be PAINFUL
  • Buggy or poorly documented 3rd party libraries (e.g. RoboGuice poorly documented)
  • RoboGuice 2.0 and AndroidAnnotations 2.7 do not work together
  • Robolectric does not support API level 17
  • Robolectric and ActionBarSherlock do not like each others
  • Killing the activity causes static variables to be null (if initialized in some other activity than the returning one)
  • Rotating the screen crashes the app (because re-creates the activity)