You are on page 1of 40

Android Mobile Phone Development

Me First
http://stuff

Computer
Stuff data
Stuff

x 10

neidetcher.com/android.html
Why Android?
Big Picture
No Money | iPhone Dominates

Job Listing Comparison


May 9, 2009

simplyhired.com

dice.com

android java
iPhone
indeed.com j2me

monster.com

careerbuilder.com

0 200 400 600 800 1000 1200 1400 1600


No Money | Hackable & Pervasive?
● Canonical is creating framework to run Android apps
on Ubuntu (netbook remix?)
http://www.engadget.com/2009/05/26/canonical-giving-ubuntu-the-gift-of-android-apps/


XML VM is porting Android apps to iPhone
http://www.xmlvm.org/android/

● ASE to script for and on the phone (Lua, Python)


http://code.google.com/p/android-scripting/

● iPhone vs Android Dev Comparison


http://greensopinion.blogspot.com/2009/07/android-versus-iphone-development.html

● Garmin Adopts Android


http://techgeist.net/2009/06/garmin-officially-adopts-android-ditches-in-house-linux-os/

● Android on a Sony?
http://www.engadget.com/2009/06/08/sony-building-android-based-walkman-and-pnd-for-2010-launch/
http://phandroid.com/2009/07/04/sony-ericsson-making-xperia-android-holy-smokes/
Android | Timeline
● 2001: Google starts filing mobile patents
● 2005 July: Google Acquires Android Inc
● 2005 Oct: Dan Bornstein joins Google to work on Dalvik
● 2007 Nov: Open Handset Alliance is formed and Android
SDK is released
● 2008 Oct: T-Mobile G1 is released
● 2009 Jan: Palm Pre announced
● 2009 Feb: Pay apps available on market
● 2009 Jun: Samsung Android phones in EU
● 2009 Nov: Motorola releasing Android phone
● 2009 Aug: new T-Mobile Android phone
● 2009: Possible Acer, Dell and HP net-books
Android | Open Handset Alliance
47 Companies
Sprint, T-Mobile,
Telecom Italia,
Vodafone, Intel, Texas
Instruments, NVIDIA,
Asus, Garmin, HTC,
LG, Motorola,
Samsung, Sony,
Toshiba...
Android | Market

http://market.android.com/publish/Home
Android
● Built on Linux
● Not POSIX
● Custom C library
(bionic)
Android
is a Linux

Android has many


Dalvik VM Dalvik VMs
Dalvik VM
Dalvik VM

http://source.android.com/download
Android | Open Source
Runtime Stack Development Stack

Apache Harmony: Apache2 QEMU: LGPL

JFree Chart: LGPL


SQLite: Public Domain WebKit: LGPLv2

JCommon: BSD

Android: Apache2 Bionic: BSD


Eclipse: EPL

Linux: GPLv2
Android | Architecture

Home Contacts
Map Phone Browser Email

Telephony Activity Location Notification Package

Core Libraries

SQLite WebKit OpenGL bionic


Dalvik VM

WiFi Driver
WiFi Camera Power Display Keypad
Android | Google IO
● 3 types of agreements
● 3 Ways to code
● 20 handsets in 2009
● Oprah moment
● Donut
● Universal search where universe is phone
● Text to speech
● Gestures/ handwriting recognition

http://www.flickr.com/photos/francois/3959737/
Dalvik

● Different
beast
● Not Java

byte code
● Not JVM
Dalvik | Background
● Dan Bornstein joined
Google 2005
● Made for low end
machines
● low ram (no disk swap
space)
● battery
● Register based (not
stack based)
● No JIT (it's on the road
map) http://www.flickr.com/photos/fremat/447395038/sizes/l/
Dalvik | Pro/ Con of Approach
● All those Java ● James Gosling

coders hates you


● All that tooling ● Sun (Oracle) hates

● Don't have to deal you


with Sun and JCP ● Java fragmentation
● Optimize byte-code ● No more write once

for hardware run everywhere

http://www.flickr.com/photos/catwommn/3374184512/
Dalvik | .dex vs .class
● Single constant pool
for all classes
120

100 Compression
● Uncompressed
libs
browser app
alarm ap p

80

● More pointing 60

40

● More sharing
20

0
uncompressed jar compressed jar uncompressed dex

http://retrodev.com/android/dexformat.html
http://sites.google.com/site/io/dalvik-vm-internals (handouts)
Dalvik | Other Languages?
● Java FX runs on Android (JavaOne
2008)
● Anything that dynamically reads .class

files or dynamically manipulates Java


binaries won't work without Android
specific tweaks
● scala works

● http://www.youtube.com/watch?v=BtUX-GS36o8&feature=related
● http://www.ibm.com/developerworks/opensource/library/os-eclipse-scala/
Dalvik | Sandbox
● Every app is a process
● process gets its own
user id
● files is sandboxed
● SQLite DB is
sandboxed (just files
anyways)

http://www.flickr.com/photos/bauchidgw/2820627227/
Dalvik | Zygote
Home
Every new app isn't a VM cold start
Minimize memory requirements by
Application
Code
sharing what we can
Map
Zygote
Application
System Code
System
Libraries Browser
Libraries

Application
Code

Email ●Android creates Zygote at startup


●Zygote loads up system libraries
Application
Code ●Zygote finds out new app is starting

●Zygote forks process, giving all Dalvik VMs

(and apps) access to system libraries


Dalvik | Application Stack

Activity
Back button
Manager does a pop
on the stack

Map

Browser

Email
Low memory killer
Home will look at LRU apps
to destroy
Development

● It's easy
● Write code in Java

● Lots of tooling

● Lots of documentation
Dev | Books

Amazon has 7 books total (Jun 14, 2009)


Dev | Get Started

● Android SDK
● http://developer.android.com/sdk
● local documentation

● tools

● Eclipse plugin
● http://dl-ssl.google.com/android/eclipse/
android.*
Dev | APIs dalvik.* junit.framework
junit.runner
http://developer.android.com/reference/packages.html org.apache.http
org.json
org.w3c.dom
java.awt.font java.util.logging
java.beans java.util.prefs
org.xml.sax
java.io java.util.regex org.xmlpull.v1
java.lang java.util.zip org.xmlpull.v1.sax2
java.lang.annotation javax.crypto
java.lang.ref javax.microedition.khronos.egl
java.lang.reflect javax.microedition.khronos.opengles
java.math javax.net
java.net javax.security.auth
java.nio javax.security.auth.callback
java.security javax.security.auth.login
java.sql javax.security.auth.x500
java.text javax.security.cert
java.util javax.sql
java.util.concurrent javax.xml
java.util.jar

...but
rd
Dev | 3 Party & Workaround
rd

You can use 3 Party APIs
●If you need J2SE APIs that

aren't there then include them


from Apache Harmony

● SCMXL (Apache State Chart XML project) has a good write-up


http://commons.apache.org/scxml/usecases/scxml-stopwatch-on-android.html
Dev | Resource Class
mk19:~/code/scrumpoker>cat src/com/neidetcher/scrumpoker/R.java
/* AUTO-GENERATED FILE. DO NOT MODIFY.
*
* This class was automatically generated by the
* aapt tool from the resource data it found. It
mk19:~/code/scrumpoker>tree * should not be modified by hand.
*/
.
|-- ... package com.neidetcher.scrumpoker;
|-- res
public final class R {
| |-- drawable public static final class attr {
| | `-- refres h.png }
public static final class drawable {
| |-- layout
public static final int refres h=0x7f020000;
| | |-- dis pla y.xml }
| | `-- m a in.xml public static final class id {
public static final int displayPointsTextView=0x7f050000;
| `-- values public static final int pointsListView=0x7f050001;
| `-- s tring s .xml }
public static final class layout {
`-- src public static final int dis pla y=0x7f030000;
`-- ... public static final int m a in=0x7f030001;
}
public static final class s tring {
public static final int app_name=0x7f040000;
aapt }
}
Dev | Activity
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"

Dev | View android:orientation="vertical"


android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:id="@+id/displayPointsTextView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:height="400sp"
android:width="300sp"
android:textColor="#FFF"
android:gravity="center_horizontal|center_vertical"
android:textSize="210sp"
/>
</LinearLayout>
public class DisplayActivity extends Activity
{
TextView myTextView = null;

@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.display);

// set value for the text


myTextView = (TextView) findViewById(
R.id.displayPointsTextView);
String points = getIntent().getExtras().getString(
ScrumPokerActivity.SELECTED_POINTS);
if (points.equals("100"))
{
myTextView.setTextSize(180);
}

myTextView.setText(points);
}
}
Dev | Intents
Activity1 Intent Activity2

create(Activity2)

putExtra(key, value)

startActivity(intent)

onCreate
getIntent()

getExtras.get(key):value

● Open Intents
http://www.openintents.org/en/
Dev | Intents & Mashability
InterTubes

wheels down in PST


YourApp
FTW!!!
classes.dex

NarcissisticProxy

TzChangeReceiverActivity
Location
AndroidManifext.xml
Manager
receiver
intent:ACTION_TIMEZONE_CHANGED
Dev | Packaging
.java .class

.java javac .class dx

.java .class

.xml
aapt classes
.xml
.dex
.png

.xml classes
.dex
.xml

.png .apk
Dev | apk
shiv:~/play>jar -xvf "Scrum Poker.apk"
shiv:~/play>tree
.
|-- AndroidManifest.xml
|-- Scrum Poker.apk
|-- classes.dex
|-- res
| |-- drawable
| | `-- refresh.png
| `-- layout
| |-- display.xml
| `-- main.xml
`-- resources.arsc

3 directories, 7 files
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{

Dev | dexdump
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

displayPointsListView = (ListView) findViewById(R.id.pointsListView);


int layoutId = android.R.layout.simple_list_item_1;

// populate the list view with an array


ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this,
layoutId, POINTS);
displayPointsListView.setAdapter(arrayAdapter);
Virtual methods - displayPointsListView.setOnItemClickListener(mMessageClickedHandler);
#0 : (in Lcom/neidetcher/scrumpoker/ScrumPoker;)
}
name : 'onCreate'
type : '(Landroid/os/Bundle;)V'
access : 0x0001 (PUBLIC)
code -
registers : 5
shiv:~/play>~/opt/android-sdk-linux_x86-1.0_r2/tools/dexdump
ins : 2 -d classes.dex
outs : 4
insns size : 47 16-bit code units
000ad8: |[000ad8] com.neidetcher.scrumpoker.ScrumPoker.onCreate:(Landroid/os/Bundle;)V
000ae8: 6f20 0100 4300 |0000: invoke-super {v3, v4}, Landroid/app/Activity;.onCreate:(Landroid/os/Bundle;)V // method
000aee: 1401 0100 037f |0003: const v1, #float 174128887730233583002069148843976425472.000000 // #7f030001
000af4: 6e20 1e00 1300 |0006: invoke-virtual {v3, v1}, Lcom/neidetcher/scrumpoker/ScrumPoker;.setContentView:(I)V //
000afa: 1401 0100 057f |0009: const v1, #float 176787343721803414747876762964537114624.000000 // #7f050001
000b00: 6e20 1c00 1300 |000c: invoke-virtual {v3, v1}, Lcom/neidetcher/scrumpoker/ScrumPoker;.findViewById:(I)Landroi
000b06: 0c01 |000f: move-result-object v1
000b08: 1f01 0d00 |0010: check-cast v1, Landroid/widget/ListView; // class@000d
000b0c: 5b31 0d00 |0012: iput-object v1, v3, Lcom/neidetcher/scrumpoker/ScrumPoker;.myListView:Landroid/widget/L
000b10: 1400 0300 0901 |0014: const v0, #float 0.000000 // #01090003
000b16: 2201 0b00 |0017: new-instance v1, Landroid/widget/ArrayAdapter; // class@000b
000b1a: 5432 0800 |0019: iget-object v2, v3, Lcom/neidetcher/scrumpoker/ScrumPoker;.POINTS:[Ljava/lang/String; /
000b1e: 7040 0700 3120 |001b: invoke-direct {v1, v3, v0, v2}, Landroid/widget/ArrayAdapter;.<init>:(Landroid/content/
000b24: 5b31 0c00 |001e: iput-object v1, v3, Lcom/neidetcher/scrumpoker/ScrumPoker;.myArrayAdapter:Landroid/widg
000b28: 5431 0d00 |0020: iget-object v1, v3, Lcom/neidetcher/scrumpoker/ScrumPoker;.myListView:Landroid/widget/L
000b2c: 5432 0c00 |0022: iget-object v2, v3, Lcom/neidetcher/scrumpoker/ScrumPoker;.myArrayAdapter:Landroid/widg
000b30: 6e20 0800 2100 |0024: invoke-virtual {v1, v2}, Landroid/widget/ListView;.setAdapter:(Landroid/widget/ListAdap
000b36: 5431 0d00 |0027: iget-object v1, v3, Lcom/neidetcher/scrumpoker/ScrumPoker;.myListView:Landroid/widget/L
000b3a: 5432 0b00 |0029: iget-object v2, v3, Lcom/neidetcher/scrumpoker/ScrumPoker;.mMessageClickedHandler:Landr
field@000b
000b3e: 6e20 0900 2100 |002b: invoke-virtual {v1, v2}, Landroid/widget/ListView;.setOnItemClickListener:(Landroid/wid
000b44: 0e00 |002e: return-void
catches : (none)
positions :
Dev | Install Time
● What happens when you install the
.dex software...
● there is no JIT
● security
dexopt
● verification of dex files
● Optimization
● specific to hardware
● inlining
.odex ● pruning
● static linking
http://www.netmite.com/android/mydroid/dalvik/docs/dexopt.html
Dev | Good Android Code
● sleep, react quickly, sleep
● avoid allocation

Address[] addressArray = mgr.findAddresses()


for(int ii = 0; ii < addressArray.length; ii++)

Address[] addressArray = mgr.findAddresses()


for(Address currAddress : addressArray)

List<Address> addresses = mgr.findAddresses();


for(Address currAddress : addresses)

http://kohlerm.blogspot.com/2009/04/analyzing-memory-usage-off-your-android.html
Dev | Gotchas
● I accidentally imported the "super R" instead of
my locally generated R. (2 hours)
● View layouts can't be camel cased. (30 minutes)
● The tools directory in the Android SDK needs be
set to executable to run and for the Eclipse
plug-in to work. (10 minutes)
● If your install didn't work on the phone you see a
deceptive green check-mark. (10 minutes)
● Don't put heavy object graphs in putExtra()
● Development upgrade to Cupcake was kludgy for me
One More Thing | NDK
● Native Dev Kit
● C/ C++
● Consistent libs
● Docs, tutorials, code
● Transparent to user
http://android-developers.blogspot.com/2009/06/introducing-android-15-ndk-release-1.html

http://www.flickr.com/photos/sin_agua/2208439930/
Dev | Eclipse Plugin

●Logging
●Emulator

●Hierarchy Viewer

●ADB
Questions?
http://neidetcher.com/android.html

You might also like