introduction to android by demian neidetcher
DESCRIPTION
Demian Neidetcher's presentation to the Denver Open Source Users Group on the Android mobile phone platform. Full details and source code available at http://neidetcher.com/android.htmlTRANSCRIPT
Android Mobile Phone Development
ContextAndroid
Dalvik
Development
Me First
dataStuff
ComputerStuff
http://stuff
x 10
neidetcher.com/android.html
Context | 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: Possible Acer, Dell and HP net-books
http://www.flickr.com/photos/ram_/1637873367/sizes/l/
Context | Open Handset Alliance
47 Companies
Sprint, T-Mobile, Telecom Italia, Vodafone, Intel, Texas Instruments, NVIDIA, Asus, Garmin, HTC, LG, Motorola, Samsung, Sony, Toshiba...
Context | Market
simplyhired.com
dice.com
indeed.com
monster.com
careerbuilder.com
0 200 400 600 800 1000 1200 1400 1600
Job Listing Comparison
May 9, 2009
android javaiPhone
j2me
how does Android’s growth compare to iPhone’s growth at launch? Our best answer: both grew more quickly than the market, but iPhone growth was much faster than Android. --admob.com
T-Mobile recently shared some statistics from the Android Market. Right now, there are about 2,300 applications
available, which is under one-tenth the size of the iPhone Apps Store's whopping 25,000+. --InformationWeek March 25, 2009
Context | Criticism
● Google helps T-Mobile block tethering● Not standard C library (Bionic)● Portions of SDK not open (yet)● Too many free apps● Android is Not POSIX● Dalvik is Not Java
http://www.flickr.com/photos/scjohnson/3475073977/
Android | Open Source
Linux: GPLv2
WebKit: LGPLv2SQLite: Public Domain
Eclipse: EPL
QEMU: LGPL
Bionic: BSDAndroid: Apache2
Apache Harmony: Apache2
Development StackRuntime Stack
JFree Chart: LGPL
JCommon: BSD
Android | MarketAndroid | Market
Android | Architecture
Dalvik VM
Core Libraries
WiFi Driver PowerWiFi Camera Keypad
WebKit
WiFi
OpenGLWebKitSQLite OpenGL bionic
ActivityTelephony NotificationActivity Location Package
Contacts
Telephony
Home Phone Browser EmailMap
Display
Dalvik | Background
● Dan Bornstein● Made for low end machines
● low ram (no disk swap space)● battery
● Register based (not stack based)● Not a JVM● No JIT (it's on the road map)
● most heavy lifting is in native code
● Does no memory management or threading
http://www.flickr.com/photos/fremat/447395038/sizes/l/
Dalvik | Pro/ Con of Approach
● All those Java codersAll those Java coders● All that toolingAll that tooling● Don't have to deal Don't have to deal with Sun and JCPwith Sun and JCP
● Optimize byte-code Optimize byte-code for hardwarefor hardware
● James Gosling James Gosling hates youhates you
● Sun hates youSun hates you● Java fragmentationJava fragmentation● No more No more write write
once run once run everywhereeverywhere
http://www.flickr.com/photos/catwommn/3374184512/http://www.flickr.com/photos/catwommn/3374184512/
Dalvik | .dex vs .class
● Single constant pool for all classes
● Uncompressed● More pointing● More sharing
http://retrodev.com/android/dexformat.html
uncompressed jar compressed jar uncompressed dex
0
20
40
60
80
100
120
libsbrowser appalarm app
http://sites.google.com/site/io/dalvik-vm-internals (handouts)
Compression
Dalvik | Other Languages?Dalvik | Other Languages?
anything that dynamically reads .class files or dynamically manipulates Java binaries won't work without Android specific tweaksscala works :)
http://chneukirchen.org/blog/archive/2009/04/programming-for-android-with-scala.html
Dalvik | Zygote
●Android creates Zygote at startup●Zygote loads up system libraries●Zygote finds out new app is starting●Zygote forks process, giving all Dalvik VMs (and apps) access to system libraries
Every new app isn't a VM cold startMinimize memory requirements by
sharing what we can
SystemLibraries
Zygote
Home
ApplicationCode
SystemLibrariesSystemLibraries
ApplicationCode
ApplicationCode
ApplicationCode
Browser
Map
Dalvik | SandboxDalvik | Sandbox
● Every app is a processEvery app is a process● process gets its own process gets its own
user iduser id● files is sandboxedfiles is sandboxed● SQLite DB is SQLite DB is
sandboxedsandboxed
http://www.flickr.com/photos/bauchidgw/2820627227/http://www.flickr.com/photos/bauchidgw/2820627227/
Dalvik | Application Stack
Home
Browser
Map
ActivityManager
Low memory killerwill look at LRU apps to destroy
Back buttondoes a popon the stack
Dev | Get StartedDev | Get Started
● Android SDKAndroid SDK● http://developer.android.com/sdkhttp://developer.android.com/sdk● local documentationlocal documentation● toolstools
● Eclipse pluginEclipse plugin● http://dl-ssl.google.com/android/eclipse/http://dl-ssl.google.com/android/eclipse/
Dev | APIs
http://developer.android.com/reference/packages.html
java.awt.font java.beans java.io java.lang java.lang.annotation java.lang.ref java.lang.reflect java.math java.net java.nio java.security java.sql java.text java.util java.util.concurrent java.util.jar
junit.frameworkjunit.runnerorg.apache.httporg.jsonorg.w3c.domorg.xml.sax org.xmlpull.v1 org.xmlpull.v1.sax2
android.*dalvik.*
java.util.logging java.util.prefs java.util.regex java.util.zip javax.crypto javax.microedition.khronos.egl javax.microedition.khronos.opengles javax.net javax.security.auth javax.security.auth.callback javax.security.auth.login javax.security.auth.x500 javax.security.cert javax.sql javax.xml
Dev | Manifest.xml
manifest
application
activity
activity
<action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" />
intent-filter
Dev | Eclipse Plugin
Dev | LoggingLog.d(TAG, "position : " + position);Log.d(TAG, "selection: " + POINTS[position]);
Dev | Emulator
./emulator -skin QVGA-L
●Select AVD to run●Set up virtual SD card●Simulate network and CPU conditions
Dev | adbshiv:~/opt/android-sdk-linux_x86-1.0_r2/tools>./adb devices./adb devicesList of devices attached emulator-5554 device
shiv:~/opt/android-sdk-linux_x86-1.0_r2/tools>./adb shell# lssqlite_stmt_journalscachesdcardetcinitinit.goldfish.rcinit.rcdatasystemprocsyssbindefault.proprootdev
# cat /proc/cpuinfoProcessor : ARM926EJ-S rev 5 (v5l)BogoMIPS: 348.16Features : swp half thumb fastmult vfp edsp java CPU implementer : 0x41CPU architecture: 5TEJCPU variant : 0x0CPU part : 0x926CPU revision : 5Cache type : write-throughCache clean : not requiredCache lockdown : not supportedCache format : Harvard
Dev | Hierarchy ViewerDev | Hierarchy Viewer
shiv:~/opt/android-sdk-linux_x86-1.0_r2/tools>./hierarchyviewer shiv:~/opt/android-sdk-linux_x86-1.0_r2/tools>./hierarchyviewer Click on device > Load View HierarchyClick on device > Load View Hierarchy
Dev | Activity Life Cycle
running
starting
stopped
destroyed
paused
Dev | View
public class DisplayActivity extends Activity{
TextView myTextView = null;
@Overridepublic void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);setContentView(R.layout.display);
// set value for the textmyTextView = (TextView) findViewById(
R.id.displayPointsTextView);String points = getIntent().getExtras().getString(
ScrumPokerActivity.SELECTED_POINTS);if (points.equals("100")){
myTextView.setTextSize(180);}
myTextView.setText(points);}
}
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 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>
Dev | IntentsActivity1 Intent Activity2
create(Activity2)
putExtra(key, value)
startActivity(intent)
onCreategetIntent()
getExtras.get(key):value
Dev | Intents & Mashability
TzChangeReceiverActivity
YourApp
AndroidManifext.xml
receiver
classes.dex
intent:ACTION_TIMEZONE_CHANGED
LocationManager
NarcissisticProxy
InterTubes
wheels down in PSTK, thx, bai
Dev | Packaging
.java
.java
.java
javac
.class
.class
.class
dx
classes.dex
.xml
.xml
.png
aapt
.xml
.xml
.png
classes.dex
.apk
Dev | apkshiv:~/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
Dev | dexdump
Virtual methods - #0 : (in Lcom/neidetcher/scrumpoker/ScrumPoker;) name : 'onCreate' type : '(Landroid/os/Bundle;)V' access : 0x0001 (PUBLIC) code - registers : 5 ins : 2 outs : 4 insns size : 47 16-bit code units000ad8: |[000ad8] com.neidetcher.scrumpoker.ScrumPoker.onCreate:(Landroid/os/Bundle;)V000ae8: 6f20 0100 4300 |0000: invoke-super {v3, v4}, Landroid/app/Activity;.onCreate:(Landroid/os/Bundle;)V // method@0001000aee: 1401 0100 037f |0003: const v1, #float 174128887730233583002069148843976425472.000000 // #7f030001000af4: 6e20 1e00 1300 |0006: invoke-virtual {v3, v1}, Lcom/neidetcher/scrumpoker/ScrumPoker;.setContentView:(I)V // method@001e000afa: 1401 0100 057f |0009: const v1, #float 176787343721803414747876762964537114624.000000 // #7f050001000b00: 6e20 1c00 1300 |000c: invoke-virtual {v3, v1}, Lcom/neidetcher/scrumpoker/ScrumPoker;.findViewById:(I)Landroid/view/View; // method@001c000b06: 0c01 |000f: move-result-object v1000b08: 1f01 0d00 |0010: check-cast v1, Landroid/widget/ListView; // class@000d000b0c: 5b31 0d00 |0012: iput-object v1, v3, Lcom/neidetcher/scrumpoker/ScrumPoker;.myListView:Landroid/widget/ListView; // field@000d000b10: 1400 0300 0901 |0014: const v0, #float 0.000000 // #01090003000b16: 2201 0b00 |0017: new-instance v1, Landroid/widget/ArrayAdapter; // class@000b000b1a: 5432 0800 |0019: iget-object v2, v3, Lcom/neidetcher/scrumpoker/ScrumPoker;.POINTS:[Ljava/lang/String; // field@0008000b1e: 7040 0700 3120 |001b: invoke-direct {v1, v3, v0, v2}, Landroid/widget/ArrayAdapter;.<init>:(Landroid/content/Context;I[Ljava/lang/Object;)V // method@0007000b24: 5b31 0c00 |001e: iput-object v1, v3, Lcom/neidetcher/scrumpoker/ScrumPoker;.myArrayAdapter:Landroid/widget/ArrayAdapter; // field@000c000b28: 5431 0d00 |0020: iget-object v1, v3, Lcom/neidetcher/scrumpoker/ScrumPoker;.myListView:Landroid/widget/ListView; // field@000d000b2c: 5432 0c00 |0022: iget-object v2, v3, Lcom/neidetcher/scrumpoker/ScrumPoker;.myArrayAdapter:Landroid/widget/ArrayAdapter; // field@000c000b30: 6e20 0800 2100 |0024: invoke-virtual {v1, v2}, Landroid/widget/ListView;.setAdapter:(Landroid/widget/ListAdapter;)V // method@0008000b36: 5431 0d00 |0027: iget-object v1, v3, Lcom/neidetcher/scrumpoker/ScrumPoker;.myListView:Landroid/widget/ListView; // field@000d000b3a: 5432 0b00 |0029: iget-object v2, v3, Lcom/neidetcher/scrumpoker/ScrumPoker;.mMessageClickedHandler:Landroid/widget/AdapterView$OnItemClickListener; // field@000b000b3e: 6e20 0900 2100 |002b: invoke-virtual {v1, v2}, Landroid/widget/ListView;.setOnItemClickListener:(Landroid/widget/AdapterView$OnItemClickListener;)V // method@0009000b44: 0e00 |002e: return-void catches : (none) positions :
/** Called when the activity is first created. */@Overridepublic void onCreate(Bundle savedInstanceState){
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 arrayArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this,
layoutId, POINTS);displayPointsListView.setAdapter(arrayAdapter);displayPointsListView.setOnItemClickListener(mMessageClickedHandler);
}
shiv:~/play>~/opt/android-sdk-linux_x86-1.0_r2/tools/dexdump -d classes.dex
Dev | Install Time
● What happens when you install the software...
● there is no JIT
● security
● verification of dex files
● Optimization● specific to hardware● inlining● pruning● static linking
http://www.netmite.com/android/mydroid/dalvik/docs/dexopt.html
.odex
.dex
dexopt
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
Dev | Other Cool Stuff
● SQLite● LocationManager● Sensors
● Accelerometer● Compass
● Telephony● Blue Tooth● OpenGL● Camera● Media
Wrap Up | 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/
Wrap Up | Future
● Desktop phones● Net-books● Televisions?● GPS?
iPhoneAndroidAll Others
Good for 1 well* drink if Android does not have greater than 50% of themobile phone OS market by June 1, 2014
~Demian Neidetcher*where well is water
● The user experience will be inconsistent
● Hardware might be flaky and clunky
● IBM PC clone of the mobile market
Wrap Up | Questions?Wrap Up | Questions?
http://neidetcher.com/android.htmlhttp://neidetcher.com/android.html