bringing c and c++ games to android
TRANSCRIPT
1
Ian Ni-LewisDan GalpinGame Developer AdvocatesMay 11 2011
Feedback httpgooglNudVsAndroid
Bringing C and C++ Games to Android
About This Talk
Audience
ndash CC++ Developers
ndash Android background
ndash Game development experience
ndash No prior NDK knowledge needed
Agenda
ndash Programming Android in CC++
ndash Using the NDK
ndash Bringing your game to Android
ndash Troubleshooting tips and tricks
ndash Best practices
3
Native development on phones tablets and beyond
Programming Android in CC++
4
The NDK Provides Support for CC++ Development
NDK = Native Development Kit
Scenarios
ndash Reuse existing libraries
ndash Accelerate key subroutines
bull Access VFP and NEON
ndash Port entire games
5
C++
Whatrsquos in the Box
Toolchain
ndash Standard gcc cross-compilers
Really fancy build system
ndash Primarily written in GNU make
ndash Based on Android platform build system
Headers and libraries
ndash C and C++ runtimes
ndash Stable system interface
6
7
Application Code
Framework Classes
Runtime
Linux Kernel
JNI
Why are Headers and Libraries So Important
System Libraries
7
Application Code
Framework Classes
Runtime
Linux Kernel
JNI
Why are Headers and Libraries So Important
System Libraries
7
Application Code
Framework Classes
Runtime
Linux Kernel
JNI
Why are Headers and Libraries So Important
Your Libraries
System Libraries
7
Application Code
Framework Classes
Runtime
Linux Kernel
JNI
Why are Headers and Libraries So Important
Your Libraries
System Libraries
7
Application Code
Framework Classes
Runtime
Linux Kernel
JNI
Why are Headers and Libraries So Important
Your Libraries
System Libraries
7
Application Code
Framework Classes
Runtime
Linux Kernel
JNI
Why are Headers and Libraries So Important
Your Libraries
Stable ABI
System Libraries
8
Feature Library
C runtime libc
C++ runtime libstdc++
Math libm
Dynamic Linking libdl
Logging liblog
Zlib compression libz
OpenGL ES 11 libGLESv1_CM
OpenGL ES 20 libGLESv2
8
Feature Library
C runtime libc
C++ runtime libstdc++
Math libm
Dynamic Linking libdl
Logging liblog
Zlib compression libz
OpenGL ES 11 libGLESv1_CM
OpenGL ES 20 libGLESv2
JNI Graphics libjnigraphics
8
Feature Library
C runtime libc
C++ runtime libstdc++
Math libm
Dynamic Linking libdl
Logging liblog
Zlib compression libz
OpenGL ES 11 libGLESv1_CM
OpenGL ES 20 libGLESv2
EGL libEGL
OpenSL ES libOpenSLES
Native framework NativeActivity) libandroid
JNI Graphics libjnigraphics
What the NDK is Not
Not the end of Dalvik
Not always higher performance
Not necessarily the right choice for every game
9
Dalvik vs C++
10
C++
Flexible
Easily Extensible
Android APIAccess
AutomaticMemory
Management
Fast
Low-Level
Common onOther Platforms
How to Use the NDK
11
Installing the NDK
Download NDK from developerandroidcomsdkndk
ndash Add NDK folder to your path
ndash Install Java JDK
ndash Install Ant
Windows
ndash Install Cygwin
bull Required for debugger
bull Recommended for build scripts
12
Development Flow
13
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Development Flow Project Setup
14
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Development Flow Project Setup
14
Created by $amp($))+$)(
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Project Setup
15
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Project Setup
15
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Created Manually
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Set up project
Write makefiles
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
$ampampampltPamp$(+)+-00+1234567QL6IER$ampampAgt++++++)+05BC0DE85$ampampampJ++++++++)+4B9C$ampamp$MJ++++++++++)+61B5+61B53NS
APP_STL = gnustl_static
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
$ampampampltPamp$(+)+-00+1234567QL6IER$ampampAgt++++++)+05BC0DE85$ampampampJ++++++++)+4B9C$ampamp$MJ++++++++++)+61B5+61B53NS
APP_STL = gnustl_static
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Interface Classes
Write interface in Java
ndash Use amp) keyword
17
LTC+I1K846I54KC0DE85U
QQ+H6LL6+VI6+8R5N+05B662
L9B05+0WW+GDPXJ5B+YR84W+$R5N5R2+Z
++WRR5+Z++++gt2WR1K0I45B662-[C0DE85[7U++
++Q]]+++]+^L61+_54R`+R`+9668R+N5_+_54R`+++]+^L61+`5C`R+R`+9668R+N5_+`5C`R+++]Q+++L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7U+++L9B05+WRR5+8R5N+NI54+WRL-7U
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
PXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]LPXJ8Na+EIBER+IBEa+E58R+a+E58R+B7+Z
++E0WW+0W++-]LPXJ8N73dGRBER0WW-LPXJ8Na+IBE7U
++E1R`I4J+54++-]LPXJ8N73dGRR`I4J-+++++++++++++++++++++++++++++LPXJ8Na+0Wa+[RTm2N8RW[a+[-n7=[7U
++-]LPXJ8N73d00=I54R`I4-LPXJ8Na+IBEa+54a+PXJltA7U
Development Flow Calling Dalvik Code Within CC++
20
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Build and Deploy
gt=0Alt-amp49BCDBEFG6HI
ndash Builds C libraries and emits so files
gt)-3
ndash (or ant release)
ndash Builds Java classes apk package
gtamp=44
ndash Deploys to emulator or device
21
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdbgdb-rsp over named pipe
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdb
EclipseVS
gdb-rsp over named pipe
gdb-MI
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Important Tip
B)-36amp3)$$)J23
Bringing Your Game to Android
24
Devices Accessing Android Market
25
Android 16
Android 15
Android 23
Android 233
Android 30
Two Week Period Published May 2011
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
NativeActivity is just starting
ndash 43 of checking-in devices can utilize it
ndash For non-tablet-specific titles we can take advantage of NativeActivity without becoming incompatible
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Platform-specific Resources
Using NativeActivity Compatibly
27
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dV0WcQBII0d++++cBII0+81[8IRG58C6B64[dR69cQBII0dcQ6WI96Wd
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dR69cQBII0d++++cBII0+81[8IRG58C6B64[dV0WcQBII0dcQ6WI96Wd
Using NativeActivity Compatibly
28
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
cR5N5R2+846I54)81[Kgt$XR5N$R5N5R2[+++846I54)8B04[^BII0QRWRG58C6B64[d++c1R34R+846I54)81[846I54KLLK05B81[+++++846I54)N09[W8R5N[+Qd++++++++++++++++++++++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6d++++++++++++cQR5N5R2dcR5N5R2+846I54)81[K1I$R5N5R2[+++846I54)8B04[^BII0Q8IRG58C6B64[d++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6dcQR5N5R2d
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+W8R5N$F$Ggt+)+3$XltJXm$gtltFJgt+ )+C09R50WK+k+ LL3846I5438R5NK$JMgt+)+30GgtND+3040+300IC+30G+30846I54$gt$JJMlt$ltJgt+ )+846I548R5NLLC09$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7-00+51LI6R31I490a846I54Q8R5NLLC097
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
LTC+I1KY1L0KW88C0WU
L9B05+0WW+gt$XR5N$R5N5R2+YR84W+846I54KLLKXR5N$R5N5R2+Z
++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
LTC+I1KY1L0KW88C0WU
L9B05+0WW+1I$R5N5R2+YR84W+846I54KLLK$R5N5R2+Z++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++++++gt2WR1K0I45B662-[WE85[7U++++KKK
Key Game Components
33
Lifecycle
Graphics Sound
Input
Assets
Activity LifecycleLifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Process LifecycleLifecycle
Android keeps application processes around for as long as possible
ndash Even when the activity is closed with V585W`-7 or the back key is pressed
The foreground activity process is considered the most important
ndash It can still be killed as a last resort
Visible activities are also given high priority
ndash Backgrounded activities are considered less important
ndash Processes with no active activities are killed first
Implications of the Process LifecycleLifecycle
Be careful with static initializers
ndash Your library cannot be unloaded while your process is active
bull Donrsquot assume that your static initializers will be run when your activity is created
Be careful with threads
ndash Threads are tied to the process not the activity
bull Your threads will continue to run at reduced priority even if your activity is backgrounded or destroyed
ndash Gameplay should stop during onPause
bull It might make sense to keep certain threads running - your activity may still be visible
ndash Make sure all native code is cleaned up during onDestroy
bull Users expect that your application will no longer be active when its activity is destroyed
The Basics
Key handling
ndash Your device most likely has capacitive buttons
bull Look for complete state transitions of I8m2I_8I8m2AL
bull Avoid overriding 45WLR`m2N8R
ndash Use I8m290R5L0I8m2I8Camp6WW
bull Keep your game behaving like an Android application
TouchMultitouch handling
ndash With I8I9`N8R
bull take advantage of built-in gesture processing
ndash use gt0GWR96RRI6 and GWR96RRI6
ndash Most devices now support multitouch
bull determine if your device can track distinct points
ndash `Wgt2WR1FR96-F$AltA(gtltXAJA(JgtJX)
37
Input
Other Input
Trackball handling
ndash With I86TB00N8R
bull Unhandled events turn into dpad events
Motion handling
ndash With I8gt8WI6`8C4
bull Must be registered with the gt8WI68C6
bull Disable unneeded sensors especially when paused
ndash Active sensors will quickly drain the battery
38
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
OpenGL
GLSurfaceView
ndash Creates the compatible context
bull Contexts are shared between native code and Dalvik
ndash Creates a rendering thread
ndash Releases the context during onPause
ndash Not the most efficient way to multitask withOpenGL but it avoids some driver issues
When context is lost
ndash Reload resources
bull Textures
bull Buffer objects
bull Shaders
ndash Names donrsquot persist
40
Graphics
Texture Formats
Android encourages innovation in hardware
ndash Chipset vendors use several kinds of proprietary texture compression formats
ndash OpenGL ES supports multiple compressed formats none mandatory
Solutions
ndash Uncompressed Textures
ndash Use ETC1 ndash broad support in 20
bull Optimized around photographic data
bull No Alpha
ndash Use Multi-APK (coming soon)
ndash Put textures on an asset server
bull Detect support at runtime
bull Download to each device
41
Graphics
Drawing for Performance
Draw order is important
ndash Has no impact on some platforms means everything on others
ndash Draw front to back to make best use of early rejects
Use VBOs
ndash Avoid unnecessary state changes
Textures
ndash Use power of 2 sized textures
bull It can be very slow
bull On some chipsets not all address modes work
42
Graphics
Writing Compatible Shaders
Query query
ndash Make sure to query for number of attributes varying and uniforms supported
bull Varies between devices
bull Not respecting will make your application crash
bull ldquoSupportedrdquo does not mean ldquoperforms wellrdquo
Conditions
ndash Avoid as much as possible
bull if necessary put them last in the shader
ndash Use mix() clamp() etc to create the same result
discard()
ndash Avoid discard()
bull if necessary it should be last
43
Graphics
Audio Solutions
Full track audio
s 45amp026
bull Plays multiple formats with codec support
bull Plays from filesystem or from network
bull Has high latency memory and CPU usage for quick sound effects
Sound effects and clips
s gtI984ampII0
bull Plays multiple formats with codec support
bull Preloads audio files to a pool
ndash Plays them with low latency
44
Sound
Audio Solutions
Application-generated audio
s $945I6T
bull Plays PCM audio only with minimal latency
bull Useful for applications that wish to perform sound processing or mixing
OpenSLES
ndash Combines capabilities of 45amp026 and $945I6T
ndash Available only in the NDK
ndash Requires Android 23 and higher
45
Sound
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
Use native AssetManager
ndash Gingerbread and Beyond
Targeting tricky trying tasks
Troubleshooting Tips and Tricks
47
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
One JNI Context Per Thread
Threading Options
49
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
JNI Context 2
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
OR
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
If all else fails Market filters
ndash Instruction set
ndash ARMv5ARMv7
ndash GL version
ndash Platform release
ndash Use Device Availability
Tips Standing Out from the Crowd
Start Small
ndash Download assets as-needed
ndash Hook me early instead of making me wait
Use Android backuprestore service (save to the cloud)
ndash Keep my progress when I switch devices
Support multiple control schemes
ndash Trackball D-pad virtual stick
ndash Let me decide what works best
Support install-to-SD
ndash Android Market users will knock your ratings if you donrsquot
51
Tips Standing Out from the Crowd
Profiling
ndash In-game profiling to select optimal settings per-device
Social
ndash Hook into social networks
ndash Use OpenID
Build a live wallpaper
ndash Own the userrsquos home screen with stats avatars
Analytics
ndash Market and in-game
In-app payments
ndash Consider alternative monetization techniques
52
Troubleshooting Development Tools
NVIDIA Debug Manager for Eclipse
ndash Simplifies setup for native debugger under Eclipse
bull developernvidiacomtegranvidia-debug-manager-android-ndk
WinGDB
ndash Use Visual Studio to debug Android NDK applications
bull wwwwingdbcom
vs-android
ndash Native MSBuild files for Android toolchain
bull vs-androidgooglecodecom
53
Troubleshooting Performance Tools
NVIDIA PerfHUD ES
ndash developernvidiacomtegraperfhud-es
Adreno Profiler
ndash developerqualcommcomshowcaseadreno-profiler
POWERVR Insider Utilities
ndash Including PVRTrace and PVRTune
ndash wwwimgteccompowervrinsiderpowervr-utilitiesasp
54
developerandroidcomsdkndkGoogleGameDevAndroid
Feedback httpgooglNudVs
QampA
55
Ian Ni-LewisDan GalpinGame Developer AdvocatesMay 11 2011
Feedback httpgooglNudVsAndroid
Bringing C and C++ Games to Android
About This Talk
Audience
ndash CC++ Developers
ndash Android background
ndash Game development experience
ndash No prior NDK knowledge needed
Agenda
ndash Programming Android in CC++
ndash Using the NDK
ndash Bringing your game to Android
ndash Troubleshooting tips and tricks
ndash Best practices
3
Native development on phones tablets and beyond
Programming Android in CC++
4
The NDK Provides Support for CC++ Development
NDK = Native Development Kit
Scenarios
ndash Reuse existing libraries
ndash Accelerate key subroutines
bull Access VFP and NEON
ndash Port entire games
5
C++
Whatrsquos in the Box
Toolchain
ndash Standard gcc cross-compilers
Really fancy build system
ndash Primarily written in GNU make
ndash Based on Android platform build system
Headers and libraries
ndash C and C++ runtimes
ndash Stable system interface
6
7
Application Code
Framework Classes
Runtime
Linux Kernel
JNI
Why are Headers and Libraries So Important
System Libraries
7
Application Code
Framework Classes
Runtime
Linux Kernel
JNI
Why are Headers and Libraries So Important
System Libraries
7
Application Code
Framework Classes
Runtime
Linux Kernel
JNI
Why are Headers and Libraries So Important
Your Libraries
System Libraries
7
Application Code
Framework Classes
Runtime
Linux Kernel
JNI
Why are Headers and Libraries So Important
Your Libraries
System Libraries
7
Application Code
Framework Classes
Runtime
Linux Kernel
JNI
Why are Headers and Libraries So Important
Your Libraries
System Libraries
7
Application Code
Framework Classes
Runtime
Linux Kernel
JNI
Why are Headers and Libraries So Important
Your Libraries
Stable ABI
System Libraries
8
Feature Library
C runtime libc
C++ runtime libstdc++
Math libm
Dynamic Linking libdl
Logging liblog
Zlib compression libz
OpenGL ES 11 libGLESv1_CM
OpenGL ES 20 libGLESv2
8
Feature Library
C runtime libc
C++ runtime libstdc++
Math libm
Dynamic Linking libdl
Logging liblog
Zlib compression libz
OpenGL ES 11 libGLESv1_CM
OpenGL ES 20 libGLESv2
JNI Graphics libjnigraphics
8
Feature Library
C runtime libc
C++ runtime libstdc++
Math libm
Dynamic Linking libdl
Logging liblog
Zlib compression libz
OpenGL ES 11 libGLESv1_CM
OpenGL ES 20 libGLESv2
EGL libEGL
OpenSL ES libOpenSLES
Native framework NativeActivity) libandroid
JNI Graphics libjnigraphics
What the NDK is Not
Not the end of Dalvik
Not always higher performance
Not necessarily the right choice for every game
9
Dalvik vs C++
10
C++
Flexible
Easily Extensible
Android APIAccess
AutomaticMemory
Management
Fast
Low-Level
Common onOther Platforms
How to Use the NDK
11
Installing the NDK
Download NDK from developerandroidcomsdkndk
ndash Add NDK folder to your path
ndash Install Java JDK
ndash Install Ant
Windows
ndash Install Cygwin
bull Required for debugger
bull Recommended for build scripts
12
Development Flow
13
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Development Flow Project Setup
14
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Development Flow Project Setup
14
Created by $amp($))+$)(
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Project Setup
15
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Project Setup
15
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Created Manually
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Set up project
Write makefiles
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
$ampampampltPamp$(+)+-00+1234567QL6IER$ampampAgt++++++)+05BC0DE85$ampampampJ++++++++)+4B9C$ampamp$MJ++++++++++)+61B5+61B53NS
APP_STL = gnustl_static
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
$ampampampltPamp$(+)+-00+1234567QL6IER$ampampAgt++++++)+05BC0DE85$ampampampJ++++++++)+4B9C$ampamp$MJ++++++++++)+61B5+61B53NS
APP_STL = gnustl_static
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Interface Classes
Write interface in Java
ndash Use amp) keyword
17
LTC+I1K846I54KC0DE85U
QQ+H6LL6+VI6+8R5N+05B662
L9B05+0WW+GDPXJ5B+YR84W+$R5N5R2+Z
++WRR5+Z++++gt2WR1K0I45B662-[C0DE85[7U++
++Q]]+++]+^L61+_54R`+R`+9668R+N5_+_54R`+++]+^L61+`5C`R+R`+9668R+N5_+`5C`R+++]Q+++L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7U+++L9B05+WRR5+8R5N+NI54+WRL-7U
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
PXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]LPXJ8Na+EIBER+IBEa+E58R+a+E58R+B7+Z
++E0WW+0W++-]LPXJ8N73dGRBER0WW-LPXJ8Na+IBE7U
++E1R`I4J+54++-]LPXJ8N73dGRR`I4J-+++++++++++++++++++++++++++++LPXJ8Na+0Wa+[RTm2N8RW[a+[-n7=[7U
++-]LPXJ8N73d00=I54R`I4-LPXJ8Na+IBEa+54a+PXJltA7U
Development Flow Calling Dalvik Code Within CC++
20
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Build and Deploy
gt=0Alt-amp49BCDBEFG6HI
ndash Builds C libraries and emits so files
gt)-3
ndash (or ant release)
ndash Builds Java classes apk package
gtamp=44
ndash Deploys to emulator or device
21
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdbgdb-rsp over named pipe
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdb
EclipseVS
gdb-rsp over named pipe
gdb-MI
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Important Tip
B)-36amp3)$$)J23
Bringing Your Game to Android
24
Devices Accessing Android Market
25
Android 16
Android 15
Android 23
Android 233
Android 30
Two Week Period Published May 2011
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
NativeActivity is just starting
ndash 43 of checking-in devices can utilize it
ndash For non-tablet-specific titles we can take advantage of NativeActivity without becoming incompatible
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Platform-specific Resources
Using NativeActivity Compatibly
27
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dV0WcQBII0d++++cBII0+81[8IRG58C6B64[dR69cQBII0dcQ6WI96Wd
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dR69cQBII0d++++cBII0+81[8IRG58C6B64[dV0WcQBII0dcQ6WI96Wd
Using NativeActivity Compatibly
28
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
cR5N5R2+846I54)81[Kgt$XR5N$R5N5R2[+++846I54)8B04[^BII0QRWRG58C6B64[d++c1R34R+846I54)81[846I54KLLK05B81[+++++846I54)N09[W8R5N[+Qd++++++++++++++++++++++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6d++++++++++++cQR5N5R2dcR5N5R2+846I54)81[K1I$R5N5R2[+++846I54)8B04[^BII0Q8IRG58C6B64[d++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6dcQR5N5R2d
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+W8R5N$F$Ggt+)+3$XltJXm$gtltFJgt+ )+C09R50WK+k+ LL3846I5438R5NK$JMgt+)+30GgtND+3040+300IC+30G+30846I54$gt$JJMlt$ltJgt+ )+846I548R5NLLC09$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7-00+51LI6R31I490a846I54Q8R5NLLC097
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
LTC+I1KY1L0KW88C0WU
L9B05+0WW+gt$XR5N$R5N5R2+YR84W+846I54KLLKXR5N$R5N5R2+Z
++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
LTC+I1KY1L0KW88C0WU
L9B05+0WW+1I$R5N5R2+YR84W+846I54KLLK$R5N5R2+Z++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++++++gt2WR1K0I45B662-[WE85[7U++++KKK
Key Game Components
33
Lifecycle
Graphics Sound
Input
Assets
Activity LifecycleLifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Process LifecycleLifecycle
Android keeps application processes around for as long as possible
ndash Even when the activity is closed with V585W`-7 or the back key is pressed
The foreground activity process is considered the most important
ndash It can still be killed as a last resort
Visible activities are also given high priority
ndash Backgrounded activities are considered less important
ndash Processes with no active activities are killed first
Implications of the Process LifecycleLifecycle
Be careful with static initializers
ndash Your library cannot be unloaded while your process is active
bull Donrsquot assume that your static initializers will be run when your activity is created
Be careful with threads
ndash Threads are tied to the process not the activity
bull Your threads will continue to run at reduced priority even if your activity is backgrounded or destroyed
ndash Gameplay should stop during onPause
bull It might make sense to keep certain threads running - your activity may still be visible
ndash Make sure all native code is cleaned up during onDestroy
bull Users expect that your application will no longer be active when its activity is destroyed
The Basics
Key handling
ndash Your device most likely has capacitive buttons
bull Look for complete state transitions of I8m2I_8I8m2AL
bull Avoid overriding 45WLR`m2N8R
ndash Use I8m290R5L0I8m2I8Camp6WW
bull Keep your game behaving like an Android application
TouchMultitouch handling
ndash With I8I9`N8R
bull take advantage of built-in gesture processing
ndash use gt0GWR96RRI6 and GWR96RRI6
ndash Most devices now support multitouch
bull determine if your device can track distinct points
ndash `Wgt2WR1FR96-F$AltA(gtltXAJA(JgtJX)
37
Input
Other Input
Trackball handling
ndash With I86TB00N8R
bull Unhandled events turn into dpad events
Motion handling
ndash With I8gt8WI6`8C4
bull Must be registered with the gt8WI68C6
bull Disable unneeded sensors especially when paused
ndash Active sensors will quickly drain the battery
38
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
OpenGL
GLSurfaceView
ndash Creates the compatible context
bull Contexts are shared between native code and Dalvik
ndash Creates a rendering thread
ndash Releases the context during onPause
ndash Not the most efficient way to multitask withOpenGL but it avoids some driver issues
When context is lost
ndash Reload resources
bull Textures
bull Buffer objects
bull Shaders
ndash Names donrsquot persist
40
Graphics
Texture Formats
Android encourages innovation in hardware
ndash Chipset vendors use several kinds of proprietary texture compression formats
ndash OpenGL ES supports multiple compressed formats none mandatory
Solutions
ndash Uncompressed Textures
ndash Use ETC1 ndash broad support in 20
bull Optimized around photographic data
bull No Alpha
ndash Use Multi-APK (coming soon)
ndash Put textures on an asset server
bull Detect support at runtime
bull Download to each device
41
Graphics
Drawing for Performance
Draw order is important
ndash Has no impact on some platforms means everything on others
ndash Draw front to back to make best use of early rejects
Use VBOs
ndash Avoid unnecessary state changes
Textures
ndash Use power of 2 sized textures
bull It can be very slow
bull On some chipsets not all address modes work
42
Graphics
Writing Compatible Shaders
Query query
ndash Make sure to query for number of attributes varying and uniforms supported
bull Varies between devices
bull Not respecting will make your application crash
bull ldquoSupportedrdquo does not mean ldquoperforms wellrdquo
Conditions
ndash Avoid as much as possible
bull if necessary put them last in the shader
ndash Use mix() clamp() etc to create the same result
discard()
ndash Avoid discard()
bull if necessary it should be last
43
Graphics
Audio Solutions
Full track audio
s 45amp026
bull Plays multiple formats with codec support
bull Plays from filesystem or from network
bull Has high latency memory and CPU usage for quick sound effects
Sound effects and clips
s gtI984ampII0
bull Plays multiple formats with codec support
bull Preloads audio files to a pool
ndash Plays them with low latency
44
Sound
Audio Solutions
Application-generated audio
s $945I6T
bull Plays PCM audio only with minimal latency
bull Useful for applications that wish to perform sound processing or mixing
OpenSLES
ndash Combines capabilities of 45amp026 and $945I6T
ndash Available only in the NDK
ndash Requires Android 23 and higher
45
Sound
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
Use native AssetManager
ndash Gingerbread and Beyond
Targeting tricky trying tasks
Troubleshooting Tips and Tricks
47
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
One JNI Context Per Thread
Threading Options
49
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
JNI Context 2
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
OR
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
If all else fails Market filters
ndash Instruction set
ndash ARMv5ARMv7
ndash GL version
ndash Platform release
ndash Use Device Availability
Tips Standing Out from the Crowd
Start Small
ndash Download assets as-needed
ndash Hook me early instead of making me wait
Use Android backuprestore service (save to the cloud)
ndash Keep my progress when I switch devices
Support multiple control schemes
ndash Trackball D-pad virtual stick
ndash Let me decide what works best
Support install-to-SD
ndash Android Market users will knock your ratings if you donrsquot
51
Tips Standing Out from the Crowd
Profiling
ndash In-game profiling to select optimal settings per-device
Social
ndash Hook into social networks
ndash Use OpenID
Build a live wallpaper
ndash Own the userrsquos home screen with stats avatars
Analytics
ndash Market and in-game
In-app payments
ndash Consider alternative monetization techniques
52
Troubleshooting Development Tools
NVIDIA Debug Manager for Eclipse
ndash Simplifies setup for native debugger under Eclipse
bull developernvidiacomtegranvidia-debug-manager-android-ndk
WinGDB
ndash Use Visual Studio to debug Android NDK applications
bull wwwwingdbcom
vs-android
ndash Native MSBuild files for Android toolchain
bull vs-androidgooglecodecom
53
Troubleshooting Performance Tools
NVIDIA PerfHUD ES
ndash developernvidiacomtegraperfhud-es
Adreno Profiler
ndash developerqualcommcomshowcaseadreno-profiler
POWERVR Insider Utilities
ndash Including PVRTrace and PVRTune
ndash wwwimgteccompowervrinsiderpowervr-utilitiesasp
54
developerandroidcomsdkndkGoogleGameDevAndroid
Feedback httpgooglNudVs
QampA
55
About This Talk
Audience
ndash CC++ Developers
ndash Android background
ndash Game development experience
ndash No prior NDK knowledge needed
Agenda
ndash Programming Android in CC++
ndash Using the NDK
ndash Bringing your game to Android
ndash Troubleshooting tips and tricks
ndash Best practices
3
Native development on phones tablets and beyond
Programming Android in CC++
4
The NDK Provides Support for CC++ Development
NDK = Native Development Kit
Scenarios
ndash Reuse existing libraries
ndash Accelerate key subroutines
bull Access VFP and NEON
ndash Port entire games
5
C++
Whatrsquos in the Box
Toolchain
ndash Standard gcc cross-compilers
Really fancy build system
ndash Primarily written in GNU make
ndash Based on Android platform build system
Headers and libraries
ndash C and C++ runtimes
ndash Stable system interface
6
7
Application Code
Framework Classes
Runtime
Linux Kernel
JNI
Why are Headers and Libraries So Important
System Libraries
7
Application Code
Framework Classes
Runtime
Linux Kernel
JNI
Why are Headers and Libraries So Important
System Libraries
7
Application Code
Framework Classes
Runtime
Linux Kernel
JNI
Why are Headers and Libraries So Important
Your Libraries
System Libraries
7
Application Code
Framework Classes
Runtime
Linux Kernel
JNI
Why are Headers and Libraries So Important
Your Libraries
System Libraries
7
Application Code
Framework Classes
Runtime
Linux Kernel
JNI
Why are Headers and Libraries So Important
Your Libraries
System Libraries
7
Application Code
Framework Classes
Runtime
Linux Kernel
JNI
Why are Headers and Libraries So Important
Your Libraries
Stable ABI
System Libraries
8
Feature Library
C runtime libc
C++ runtime libstdc++
Math libm
Dynamic Linking libdl
Logging liblog
Zlib compression libz
OpenGL ES 11 libGLESv1_CM
OpenGL ES 20 libGLESv2
8
Feature Library
C runtime libc
C++ runtime libstdc++
Math libm
Dynamic Linking libdl
Logging liblog
Zlib compression libz
OpenGL ES 11 libGLESv1_CM
OpenGL ES 20 libGLESv2
JNI Graphics libjnigraphics
8
Feature Library
C runtime libc
C++ runtime libstdc++
Math libm
Dynamic Linking libdl
Logging liblog
Zlib compression libz
OpenGL ES 11 libGLESv1_CM
OpenGL ES 20 libGLESv2
EGL libEGL
OpenSL ES libOpenSLES
Native framework NativeActivity) libandroid
JNI Graphics libjnigraphics
What the NDK is Not
Not the end of Dalvik
Not always higher performance
Not necessarily the right choice for every game
9
Dalvik vs C++
10
C++
Flexible
Easily Extensible
Android APIAccess
AutomaticMemory
Management
Fast
Low-Level
Common onOther Platforms
How to Use the NDK
11
Installing the NDK
Download NDK from developerandroidcomsdkndk
ndash Add NDK folder to your path
ndash Install Java JDK
ndash Install Ant
Windows
ndash Install Cygwin
bull Required for debugger
bull Recommended for build scripts
12
Development Flow
13
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Development Flow Project Setup
14
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Development Flow Project Setup
14
Created by $amp($))+$)(
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Project Setup
15
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Project Setup
15
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Created Manually
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Set up project
Write makefiles
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
$ampampampltPamp$(+)+-00+1234567QL6IER$ampampAgt++++++)+05BC0DE85$ampampampJ++++++++)+4B9C$ampamp$MJ++++++++++)+61B5+61B53NS
APP_STL = gnustl_static
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
$ampampampltPamp$(+)+-00+1234567QL6IER$ampampAgt++++++)+05BC0DE85$ampampampJ++++++++)+4B9C$ampamp$MJ++++++++++)+61B5+61B53NS
APP_STL = gnustl_static
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Interface Classes
Write interface in Java
ndash Use amp) keyword
17
LTC+I1K846I54KC0DE85U
QQ+H6LL6+VI6+8R5N+05B662
L9B05+0WW+GDPXJ5B+YR84W+$R5N5R2+Z
++WRR5+Z++++gt2WR1K0I45B662-[C0DE85[7U++
++Q]]+++]+^L61+_54R`+R`+9668R+N5_+_54R`+++]+^L61+`5C`R+R`+9668R+N5_+`5C`R+++]Q+++L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7U+++L9B05+WRR5+8R5N+NI54+WRL-7U
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
PXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]LPXJ8Na+EIBER+IBEa+E58R+a+E58R+B7+Z
++E0WW+0W++-]LPXJ8N73dGRBER0WW-LPXJ8Na+IBE7U
++E1R`I4J+54++-]LPXJ8N73dGRR`I4J-+++++++++++++++++++++++++++++LPXJ8Na+0Wa+[RTm2N8RW[a+[-n7=[7U
++-]LPXJ8N73d00=I54R`I4-LPXJ8Na+IBEa+54a+PXJltA7U
Development Flow Calling Dalvik Code Within CC++
20
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Build and Deploy
gt=0Alt-amp49BCDBEFG6HI
ndash Builds C libraries and emits so files
gt)-3
ndash (or ant release)
ndash Builds Java classes apk package
gtamp=44
ndash Deploys to emulator or device
21
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdbgdb-rsp over named pipe
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdb
EclipseVS
gdb-rsp over named pipe
gdb-MI
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Important Tip
B)-36amp3)$$)J23
Bringing Your Game to Android
24
Devices Accessing Android Market
25
Android 16
Android 15
Android 23
Android 233
Android 30
Two Week Period Published May 2011
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
NativeActivity is just starting
ndash 43 of checking-in devices can utilize it
ndash For non-tablet-specific titles we can take advantage of NativeActivity without becoming incompatible
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Platform-specific Resources
Using NativeActivity Compatibly
27
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dV0WcQBII0d++++cBII0+81[8IRG58C6B64[dR69cQBII0dcQ6WI96Wd
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dR69cQBII0d++++cBII0+81[8IRG58C6B64[dV0WcQBII0dcQ6WI96Wd
Using NativeActivity Compatibly
28
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
cR5N5R2+846I54)81[Kgt$XR5N$R5N5R2[+++846I54)8B04[^BII0QRWRG58C6B64[d++c1R34R+846I54)81[846I54KLLK05B81[+++++846I54)N09[W8R5N[+Qd++++++++++++++++++++++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6d++++++++++++cQR5N5R2dcR5N5R2+846I54)81[K1I$R5N5R2[+++846I54)8B04[^BII0Q8IRG58C6B64[d++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6dcQR5N5R2d
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+W8R5N$F$Ggt+)+3$XltJXm$gtltFJgt+ )+C09R50WK+k+ LL3846I5438R5NK$JMgt+)+30GgtND+3040+300IC+30G+30846I54$gt$JJMlt$ltJgt+ )+846I548R5NLLC09$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7-00+51LI6R31I490a846I54Q8R5NLLC097
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
LTC+I1KY1L0KW88C0WU
L9B05+0WW+gt$XR5N$R5N5R2+YR84W+846I54KLLKXR5N$R5N5R2+Z
++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
LTC+I1KY1L0KW88C0WU
L9B05+0WW+1I$R5N5R2+YR84W+846I54KLLK$R5N5R2+Z++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++++++gt2WR1K0I45B662-[WE85[7U++++KKK
Key Game Components
33
Lifecycle
Graphics Sound
Input
Assets
Activity LifecycleLifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Process LifecycleLifecycle
Android keeps application processes around for as long as possible
ndash Even when the activity is closed with V585W`-7 or the back key is pressed
The foreground activity process is considered the most important
ndash It can still be killed as a last resort
Visible activities are also given high priority
ndash Backgrounded activities are considered less important
ndash Processes with no active activities are killed first
Implications of the Process LifecycleLifecycle
Be careful with static initializers
ndash Your library cannot be unloaded while your process is active
bull Donrsquot assume that your static initializers will be run when your activity is created
Be careful with threads
ndash Threads are tied to the process not the activity
bull Your threads will continue to run at reduced priority even if your activity is backgrounded or destroyed
ndash Gameplay should stop during onPause
bull It might make sense to keep certain threads running - your activity may still be visible
ndash Make sure all native code is cleaned up during onDestroy
bull Users expect that your application will no longer be active when its activity is destroyed
The Basics
Key handling
ndash Your device most likely has capacitive buttons
bull Look for complete state transitions of I8m2I_8I8m2AL
bull Avoid overriding 45WLR`m2N8R
ndash Use I8m290R5L0I8m2I8Camp6WW
bull Keep your game behaving like an Android application
TouchMultitouch handling
ndash With I8I9`N8R
bull take advantage of built-in gesture processing
ndash use gt0GWR96RRI6 and GWR96RRI6
ndash Most devices now support multitouch
bull determine if your device can track distinct points
ndash `Wgt2WR1FR96-F$AltA(gtltXAJA(JgtJX)
37
Input
Other Input
Trackball handling
ndash With I86TB00N8R
bull Unhandled events turn into dpad events
Motion handling
ndash With I8gt8WI6`8C4
bull Must be registered with the gt8WI68C6
bull Disable unneeded sensors especially when paused
ndash Active sensors will quickly drain the battery
38
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
OpenGL
GLSurfaceView
ndash Creates the compatible context
bull Contexts are shared between native code and Dalvik
ndash Creates a rendering thread
ndash Releases the context during onPause
ndash Not the most efficient way to multitask withOpenGL but it avoids some driver issues
When context is lost
ndash Reload resources
bull Textures
bull Buffer objects
bull Shaders
ndash Names donrsquot persist
40
Graphics
Texture Formats
Android encourages innovation in hardware
ndash Chipset vendors use several kinds of proprietary texture compression formats
ndash OpenGL ES supports multiple compressed formats none mandatory
Solutions
ndash Uncompressed Textures
ndash Use ETC1 ndash broad support in 20
bull Optimized around photographic data
bull No Alpha
ndash Use Multi-APK (coming soon)
ndash Put textures on an asset server
bull Detect support at runtime
bull Download to each device
41
Graphics
Drawing for Performance
Draw order is important
ndash Has no impact on some platforms means everything on others
ndash Draw front to back to make best use of early rejects
Use VBOs
ndash Avoid unnecessary state changes
Textures
ndash Use power of 2 sized textures
bull It can be very slow
bull On some chipsets not all address modes work
42
Graphics
Writing Compatible Shaders
Query query
ndash Make sure to query for number of attributes varying and uniforms supported
bull Varies between devices
bull Not respecting will make your application crash
bull ldquoSupportedrdquo does not mean ldquoperforms wellrdquo
Conditions
ndash Avoid as much as possible
bull if necessary put them last in the shader
ndash Use mix() clamp() etc to create the same result
discard()
ndash Avoid discard()
bull if necessary it should be last
43
Graphics
Audio Solutions
Full track audio
s 45amp026
bull Plays multiple formats with codec support
bull Plays from filesystem or from network
bull Has high latency memory and CPU usage for quick sound effects
Sound effects and clips
s gtI984ampII0
bull Plays multiple formats with codec support
bull Preloads audio files to a pool
ndash Plays them with low latency
44
Sound
Audio Solutions
Application-generated audio
s $945I6T
bull Plays PCM audio only with minimal latency
bull Useful for applications that wish to perform sound processing or mixing
OpenSLES
ndash Combines capabilities of 45amp026 and $945I6T
ndash Available only in the NDK
ndash Requires Android 23 and higher
45
Sound
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
Use native AssetManager
ndash Gingerbread and Beyond
Targeting tricky trying tasks
Troubleshooting Tips and Tricks
47
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
One JNI Context Per Thread
Threading Options
49
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
JNI Context 2
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
OR
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
If all else fails Market filters
ndash Instruction set
ndash ARMv5ARMv7
ndash GL version
ndash Platform release
ndash Use Device Availability
Tips Standing Out from the Crowd
Start Small
ndash Download assets as-needed
ndash Hook me early instead of making me wait
Use Android backuprestore service (save to the cloud)
ndash Keep my progress when I switch devices
Support multiple control schemes
ndash Trackball D-pad virtual stick
ndash Let me decide what works best
Support install-to-SD
ndash Android Market users will knock your ratings if you donrsquot
51
Tips Standing Out from the Crowd
Profiling
ndash In-game profiling to select optimal settings per-device
Social
ndash Hook into social networks
ndash Use OpenID
Build a live wallpaper
ndash Own the userrsquos home screen with stats avatars
Analytics
ndash Market and in-game
In-app payments
ndash Consider alternative monetization techniques
52
Troubleshooting Development Tools
NVIDIA Debug Manager for Eclipse
ndash Simplifies setup for native debugger under Eclipse
bull developernvidiacomtegranvidia-debug-manager-android-ndk
WinGDB
ndash Use Visual Studio to debug Android NDK applications
bull wwwwingdbcom
vs-android
ndash Native MSBuild files for Android toolchain
bull vs-androidgooglecodecom
53
Troubleshooting Performance Tools
NVIDIA PerfHUD ES
ndash developernvidiacomtegraperfhud-es
Adreno Profiler
ndash developerqualcommcomshowcaseadreno-profiler
POWERVR Insider Utilities
ndash Including PVRTrace and PVRTune
ndash wwwimgteccompowervrinsiderpowervr-utilitiesasp
54
developerandroidcomsdkndkGoogleGameDevAndroid
Feedback httpgooglNudVs
QampA
55
Native development on phones tablets and beyond
Programming Android in CC++
4
The NDK Provides Support for CC++ Development
NDK = Native Development Kit
Scenarios
ndash Reuse existing libraries
ndash Accelerate key subroutines
bull Access VFP and NEON
ndash Port entire games
5
C++
Whatrsquos in the Box
Toolchain
ndash Standard gcc cross-compilers
Really fancy build system
ndash Primarily written in GNU make
ndash Based on Android platform build system
Headers and libraries
ndash C and C++ runtimes
ndash Stable system interface
6
7
Application Code
Framework Classes
Runtime
Linux Kernel
JNI
Why are Headers and Libraries So Important
System Libraries
7
Application Code
Framework Classes
Runtime
Linux Kernel
JNI
Why are Headers and Libraries So Important
System Libraries
7
Application Code
Framework Classes
Runtime
Linux Kernel
JNI
Why are Headers and Libraries So Important
Your Libraries
System Libraries
7
Application Code
Framework Classes
Runtime
Linux Kernel
JNI
Why are Headers and Libraries So Important
Your Libraries
System Libraries
7
Application Code
Framework Classes
Runtime
Linux Kernel
JNI
Why are Headers and Libraries So Important
Your Libraries
System Libraries
7
Application Code
Framework Classes
Runtime
Linux Kernel
JNI
Why are Headers and Libraries So Important
Your Libraries
Stable ABI
System Libraries
8
Feature Library
C runtime libc
C++ runtime libstdc++
Math libm
Dynamic Linking libdl
Logging liblog
Zlib compression libz
OpenGL ES 11 libGLESv1_CM
OpenGL ES 20 libGLESv2
8
Feature Library
C runtime libc
C++ runtime libstdc++
Math libm
Dynamic Linking libdl
Logging liblog
Zlib compression libz
OpenGL ES 11 libGLESv1_CM
OpenGL ES 20 libGLESv2
JNI Graphics libjnigraphics
8
Feature Library
C runtime libc
C++ runtime libstdc++
Math libm
Dynamic Linking libdl
Logging liblog
Zlib compression libz
OpenGL ES 11 libGLESv1_CM
OpenGL ES 20 libGLESv2
EGL libEGL
OpenSL ES libOpenSLES
Native framework NativeActivity) libandroid
JNI Graphics libjnigraphics
What the NDK is Not
Not the end of Dalvik
Not always higher performance
Not necessarily the right choice for every game
9
Dalvik vs C++
10
C++
Flexible
Easily Extensible
Android APIAccess
AutomaticMemory
Management
Fast
Low-Level
Common onOther Platforms
How to Use the NDK
11
Installing the NDK
Download NDK from developerandroidcomsdkndk
ndash Add NDK folder to your path
ndash Install Java JDK
ndash Install Ant
Windows
ndash Install Cygwin
bull Required for debugger
bull Recommended for build scripts
12
Development Flow
13
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Development Flow Project Setup
14
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Development Flow Project Setup
14
Created by $amp($))+$)(
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Project Setup
15
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Project Setup
15
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Created Manually
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Set up project
Write makefiles
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
$ampampampltPamp$(+)+-00+1234567QL6IER$ampampAgt++++++)+05BC0DE85$ampampampJ++++++++)+4B9C$ampamp$MJ++++++++++)+61B5+61B53NS
APP_STL = gnustl_static
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
$ampampampltPamp$(+)+-00+1234567QL6IER$ampampAgt++++++)+05BC0DE85$ampampampJ++++++++)+4B9C$ampamp$MJ++++++++++)+61B5+61B53NS
APP_STL = gnustl_static
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Interface Classes
Write interface in Java
ndash Use amp) keyword
17
LTC+I1K846I54KC0DE85U
QQ+H6LL6+VI6+8R5N+05B662
L9B05+0WW+GDPXJ5B+YR84W+$R5N5R2+Z
++WRR5+Z++++gt2WR1K0I45B662-[C0DE85[7U++
++Q]]+++]+^L61+_54R`+R`+9668R+N5_+_54R`+++]+^L61+`5C`R+R`+9668R+N5_+`5C`R+++]Q+++L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7U+++L9B05+WRR5+8R5N+NI54+WRL-7U
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
PXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]LPXJ8Na+EIBER+IBEa+E58R+a+E58R+B7+Z
++E0WW+0W++-]LPXJ8N73dGRBER0WW-LPXJ8Na+IBE7U
++E1R`I4J+54++-]LPXJ8N73dGRR`I4J-+++++++++++++++++++++++++++++LPXJ8Na+0Wa+[RTm2N8RW[a+[-n7=[7U
++-]LPXJ8N73d00=I54R`I4-LPXJ8Na+IBEa+54a+PXJltA7U
Development Flow Calling Dalvik Code Within CC++
20
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Build and Deploy
gt=0Alt-amp49BCDBEFG6HI
ndash Builds C libraries and emits so files
gt)-3
ndash (or ant release)
ndash Builds Java classes apk package
gtamp=44
ndash Deploys to emulator or device
21
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdbgdb-rsp over named pipe
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdb
EclipseVS
gdb-rsp over named pipe
gdb-MI
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Important Tip
B)-36amp3)$$)J23
Bringing Your Game to Android
24
Devices Accessing Android Market
25
Android 16
Android 15
Android 23
Android 233
Android 30
Two Week Period Published May 2011
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
NativeActivity is just starting
ndash 43 of checking-in devices can utilize it
ndash For non-tablet-specific titles we can take advantage of NativeActivity without becoming incompatible
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Platform-specific Resources
Using NativeActivity Compatibly
27
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dV0WcQBII0d++++cBII0+81[8IRG58C6B64[dR69cQBII0dcQ6WI96Wd
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dR69cQBII0d++++cBII0+81[8IRG58C6B64[dV0WcQBII0dcQ6WI96Wd
Using NativeActivity Compatibly
28
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
cR5N5R2+846I54)81[Kgt$XR5N$R5N5R2[+++846I54)8B04[^BII0QRWRG58C6B64[d++c1R34R+846I54)81[846I54KLLK05B81[+++++846I54)N09[W8R5N[+Qd++++++++++++++++++++++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6d++++++++++++cQR5N5R2dcR5N5R2+846I54)81[K1I$R5N5R2[+++846I54)8B04[^BII0Q8IRG58C6B64[d++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6dcQR5N5R2d
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+W8R5N$F$Ggt+)+3$XltJXm$gtltFJgt+ )+C09R50WK+k+ LL3846I5438R5NK$JMgt+)+30GgtND+3040+300IC+30G+30846I54$gt$JJMlt$ltJgt+ )+846I548R5NLLC09$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7-00+51LI6R31I490a846I54Q8R5NLLC097
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
LTC+I1KY1L0KW88C0WU
L9B05+0WW+gt$XR5N$R5N5R2+YR84W+846I54KLLKXR5N$R5N5R2+Z
++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
LTC+I1KY1L0KW88C0WU
L9B05+0WW+1I$R5N5R2+YR84W+846I54KLLK$R5N5R2+Z++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++++++gt2WR1K0I45B662-[WE85[7U++++KKK
Key Game Components
33
Lifecycle
Graphics Sound
Input
Assets
Activity LifecycleLifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Process LifecycleLifecycle
Android keeps application processes around for as long as possible
ndash Even when the activity is closed with V585W`-7 or the back key is pressed
The foreground activity process is considered the most important
ndash It can still be killed as a last resort
Visible activities are also given high priority
ndash Backgrounded activities are considered less important
ndash Processes with no active activities are killed first
Implications of the Process LifecycleLifecycle
Be careful with static initializers
ndash Your library cannot be unloaded while your process is active
bull Donrsquot assume that your static initializers will be run when your activity is created
Be careful with threads
ndash Threads are tied to the process not the activity
bull Your threads will continue to run at reduced priority even if your activity is backgrounded or destroyed
ndash Gameplay should stop during onPause
bull It might make sense to keep certain threads running - your activity may still be visible
ndash Make sure all native code is cleaned up during onDestroy
bull Users expect that your application will no longer be active when its activity is destroyed
The Basics
Key handling
ndash Your device most likely has capacitive buttons
bull Look for complete state transitions of I8m2I_8I8m2AL
bull Avoid overriding 45WLR`m2N8R
ndash Use I8m290R5L0I8m2I8Camp6WW
bull Keep your game behaving like an Android application
TouchMultitouch handling
ndash With I8I9`N8R
bull take advantage of built-in gesture processing
ndash use gt0GWR96RRI6 and GWR96RRI6
ndash Most devices now support multitouch
bull determine if your device can track distinct points
ndash `Wgt2WR1FR96-F$AltA(gtltXAJA(JgtJX)
37
Input
Other Input
Trackball handling
ndash With I86TB00N8R
bull Unhandled events turn into dpad events
Motion handling
ndash With I8gt8WI6`8C4
bull Must be registered with the gt8WI68C6
bull Disable unneeded sensors especially when paused
ndash Active sensors will quickly drain the battery
38
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
OpenGL
GLSurfaceView
ndash Creates the compatible context
bull Contexts are shared between native code and Dalvik
ndash Creates a rendering thread
ndash Releases the context during onPause
ndash Not the most efficient way to multitask withOpenGL but it avoids some driver issues
When context is lost
ndash Reload resources
bull Textures
bull Buffer objects
bull Shaders
ndash Names donrsquot persist
40
Graphics
Texture Formats
Android encourages innovation in hardware
ndash Chipset vendors use several kinds of proprietary texture compression formats
ndash OpenGL ES supports multiple compressed formats none mandatory
Solutions
ndash Uncompressed Textures
ndash Use ETC1 ndash broad support in 20
bull Optimized around photographic data
bull No Alpha
ndash Use Multi-APK (coming soon)
ndash Put textures on an asset server
bull Detect support at runtime
bull Download to each device
41
Graphics
Drawing for Performance
Draw order is important
ndash Has no impact on some platforms means everything on others
ndash Draw front to back to make best use of early rejects
Use VBOs
ndash Avoid unnecessary state changes
Textures
ndash Use power of 2 sized textures
bull It can be very slow
bull On some chipsets not all address modes work
42
Graphics
Writing Compatible Shaders
Query query
ndash Make sure to query for number of attributes varying and uniforms supported
bull Varies between devices
bull Not respecting will make your application crash
bull ldquoSupportedrdquo does not mean ldquoperforms wellrdquo
Conditions
ndash Avoid as much as possible
bull if necessary put them last in the shader
ndash Use mix() clamp() etc to create the same result
discard()
ndash Avoid discard()
bull if necessary it should be last
43
Graphics
Audio Solutions
Full track audio
s 45amp026
bull Plays multiple formats with codec support
bull Plays from filesystem or from network
bull Has high latency memory and CPU usage for quick sound effects
Sound effects and clips
s gtI984ampII0
bull Plays multiple formats with codec support
bull Preloads audio files to a pool
ndash Plays them with low latency
44
Sound
Audio Solutions
Application-generated audio
s $945I6T
bull Plays PCM audio only with minimal latency
bull Useful for applications that wish to perform sound processing or mixing
OpenSLES
ndash Combines capabilities of 45amp026 and $945I6T
ndash Available only in the NDK
ndash Requires Android 23 and higher
45
Sound
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
Use native AssetManager
ndash Gingerbread and Beyond
Targeting tricky trying tasks
Troubleshooting Tips and Tricks
47
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
One JNI Context Per Thread
Threading Options
49
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
JNI Context 2
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
OR
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
If all else fails Market filters
ndash Instruction set
ndash ARMv5ARMv7
ndash GL version
ndash Platform release
ndash Use Device Availability
Tips Standing Out from the Crowd
Start Small
ndash Download assets as-needed
ndash Hook me early instead of making me wait
Use Android backuprestore service (save to the cloud)
ndash Keep my progress when I switch devices
Support multiple control schemes
ndash Trackball D-pad virtual stick
ndash Let me decide what works best
Support install-to-SD
ndash Android Market users will knock your ratings if you donrsquot
51
Tips Standing Out from the Crowd
Profiling
ndash In-game profiling to select optimal settings per-device
Social
ndash Hook into social networks
ndash Use OpenID
Build a live wallpaper
ndash Own the userrsquos home screen with stats avatars
Analytics
ndash Market and in-game
In-app payments
ndash Consider alternative monetization techniques
52
Troubleshooting Development Tools
NVIDIA Debug Manager for Eclipse
ndash Simplifies setup for native debugger under Eclipse
bull developernvidiacomtegranvidia-debug-manager-android-ndk
WinGDB
ndash Use Visual Studio to debug Android NDK applications
bull wwwwingdbcom
vs-android
ndash Native MSBuild files for Android toolchain
bull vs-androidgooglecodecom
53
Troubleshooting Performance Tools
NVIDIA PerfHUD ES
ndash developernvidiacomtegraperfhud-es
Adreno Profiler
ndash developerqualcommcomshowcaseadreno-profiler
POWERVR Insider Utilities
ndash Including PVRTrace and PVRTune
ndash wwwimgteccompowervrinsiderpowervr-utilitiesasp
54
developerandroidcomsdkndkGoogleGameDevAndroid
Feedback httpgooglNudVs
QampA
55
The NDK Provides Support for CC++ Development
NDK = Native Development Kit
Scenarios
ndash Reuse existing libraries
ndash Accelerate key subroutines
bull Access VFP and NEON
ndash Port entire games
5
C++
Whatrsquos in the Box
Toolchain
ndash Standard gcc cross-compilers
Really fancy build system
ndash Primarily written in GNU make
ndash Based on Android platform build system
Headers and libraries
ndash C and C++ runtimes
ndash Stable system interface
6
7
Application Code
Framework Classes
Runtime
Linux Kernel
JNI
Why are Headers and Libraries So Important
System Libraries
7
Application Code
Framework Classes
Runtime
Linux Kernel
JNI
Why are Headers and Libraries So Important
System Libraries
7
Application Code
Framework Classes
Runtime
Linux Kernel
JNI
Why are Headers and Libraries So Important
Your Libraries
System Libraries
7
Application Code
Framework Classes
Runtime
Linux Kernel
JNI
Why are Headers and Libraries So Important
Your Libraries
System Libraries
7
Application Code
Framework Classes
Runtime
Linux Kernel
JNI
Why are Headers and Libraries So Important
Your Libraries
System Libraries
7
Application Code
Framework Classes
Runtime
Linux Kernel
JNI
Why are Headers and Libraries So Important
Your Libraries
Stable ABI
System Libraries
8
Feature Library
C runtime libc
C++ runtime libstdc++
Math libm
Dynamic Linking libdl
Logging liblog
Zlib compression libz
OpenGL ES 11 libGLESv1_CM
OpenGL ES 20 libGLESv2
8
Feature Library
C runtime libc
C++ runtime libstdc++
Math libm
Dynamic Linking libdl
Logging liblog
Zlib compression libz
OpenGL ES 11 libGLESv1_CM
OpenGL ES 20 libGLESv2
JNI Graphics libjnigraphics
8
Feature Library
C runtime libc
C++ runtime libstdc++
Math libm
Dynamic Linking libdl
Logging liblog
Zlib compression libz
OpenGL ES 11 libGLESv1_CM
OpenGL ES 20 libGLESv2
EGL libEGL
OpenSL ES libOpenSLES
Native framework NativeActivity) libandroid
JNI Graphics libjnigraphics
What the NDK is Not
Not the end of Dalvik
Not always higher performance
Not necessarily the right choice for every game
9
Dalvik vs C++
10
C++
Flexible
Easily Extensible
Android APIAccess
AutomaticMemory
Management
Fast
Low-Level
Common onOther Platforms
How to Use the NDK
11
Installing the NDK
Download NDK from developerandroidcomsdkndk
ndash Add NDK folder to your path
ndash Install Java JDK
ndash Install Ant
Windows
ndash Install Cygwin
bull Required for debugger
bull Recommended for build scripts
12
Development Flow
13
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Development Flow Project Setup
14
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Development Flow Project Setup
14
Created by $amp($))+$)(
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Project Setup
15
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Project Setup
15
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Created Manually
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Set up project
Write makefiles
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
$ampampampltPamp$(+)+-00+1234567QL6IER$ampampAgt++++++)+05BC0DE85$ampampampJ++++++++)+4B9C$ampamp$MJ++++++++++)+61B5+61B53NS
APP_STL = gnustl_static
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
$ampampampltPamp$(+)+-00+1234567QL6IER$ampampAgt++++++)+05BC0DE85$ampampampJ++++++++)+4B9C$ampamp$MJ++++++++++)+61B5+61B53NS
APP_STL = gnustl_static
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Interface Classes
Write interface in Java
ndash Use amp) keyword
17
LTC+I1K846I54KC0DE85U
QQ+H6LL6+VI6+8R5N+05B662
L9B05+0WW+GDPXJ5B+YR84W+$R5N5R2+Z
++WRR5+Z++++gt2WR1K0I45B662-[C0DE85[7U++
++Q]]+++]+^L61+_54R`+R`+9668R+N5_+_54R`+++]+^L61+`5C`R+R`+9668R+N5_+`5C`R+++]Q+++L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7U+++L9B05+WRR5+8R5N+NI54+WRL-7U
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
PXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]LPXJ8Na+EIBER+IBEa+E58R+a+E58R+B7+Z
++E0WW+0W++-]LPXJ8N73dGRBER0WW-LPXJ8Na+IBE7U
++E1R`I4J+54++-]LPXJ8N73dGRR`I4J-+++++++++++++++++++++++++++++LPXJ8Na+0Wa+[RTm2N8RW[a+[-n7=[7U
++-]LPXJ8N73d00=I54R`I4-LPXJ8Na+IBEa+54a+PXJltA7U
Development Flow Calling Dalvik Code Within CC++
20
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Build and Deploy
gt=0Alt-amp49BCDBEFG6HI
ndash Builds C libraries and emits so files
gt)-3
ndash (or ant release)
ndash Builds Java classes apk package
gtamp=44
ndash Deploys to emulator or device
21
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdbgdb-rsp over named pipe
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdb
EclipseVS
gdb-rsp over named pipe
gdb-MI
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Important Tip
B)-36amp3)$$)J23
Bringing Your Game to Android
24
Devices Accessing Android Market
25
Android 16
Android 15
Android 23
Android 233
Android 30
Two Week Period Published May 2011
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
NativeActivity is just starting
ndash 43 of checking-in devices can utilize it
ndash For non-tablet-specific titles we can take advantage of NativeActivity without becoming incompatible
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Platform-specific Resources
Using NativeActivity Compatibly
27
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dV0WcQBII0d++++cBII0+81[8IRG58C6B64[dR69cQBII0dcQ6WI96Wd
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dR69cQBII0d++++cBII0+81[8IRG58C6B64[dV0WcQBII0dcQ6WI96Wd
Using NativeActivity Compatibly
28
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
cR5N5R2+846I54)81[Kgt$XR5N$R5N5R2[+++846I54)8B04[^BII0QRWRG58C6B64[d++c1R34R+846I54)81[846I54KLLK05B81[+++++846I54)N09[W8R5N[+Qd++++++++++++++++++++++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6d++++++++++++cQR5N5R2dcR5N5R2+846I54)81[K1I$R5N5R2[+++846I54)8B04[^BII0Q8IRG58C6B64[d++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6dcQR5N5R2d
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+W8R5N$F$Ggt+)+3$XltJXm$gtltFJgt+ )+C09R50WK+k+ LL3846I5438R5NK$JMgt+)+30GgtND+3040+300IC+30G+30846I54$gt$JJMlt$ltJgt+ )+846I548R5NLLC09$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7-00+51LI6R31I490a846I54Q8R5NLLC097
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
LTC+I1KY1L0KW88C0WU
L9B05+0WW+gt$XR5N$R5N5R2+YR84W+846I54KLLKXR5N$R5N5R2+Z
++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
LTC+I1KY1L0KW88C0WU
L9B05+0WW+1I$R5N5R2+YR84W+846I54KLLK$R5N5R2+Z++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++++++gt2WR1K0I45B662-[WE85[7U++++KKK
Key Game Components
33
Lifecycle
Graphics Sound
Input
Assets
Activity LifecycleLifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Process LifecycleLifecycle
Android keeps application processes around for as long as possible
ndash Even when the activity is closed with V585W`-7 or the back key is pressed
The foreground activity process is considered the most important
ndash It can still be killed as a last resort
Visible activities are also given high priority
ndash Backgrounded activities are considered less important
ndash Processes with no active activities are killed first
Implications of the Process LifecycleLifecycle
Be careful with static initializers
ndash Your library cannot be unloaded while your process is active
bull Donrsquot assume that your static initializers will be run when your activity is created
Be careful with threads
ndash Threads are tied to the process not the activity
bull Your threads will continue to run at reduced priority even if your activity is backgrounded or destroyed
ndash Gameplay should stop during onPause
bull It might make sense to keep certain threads running - your activity may still be visible
ndash Make sure all native code is cleaned up during onDestroy
bull Users expect that your application will no longer be active when its activity is destroyed
The Basics
Key handling
ndash Your device most likely has capacitive buttons
bull Look for complete state transitions of I8m2I_8I8m2AL
bull Avoid overriding 45WLR`m2N8R
ndash Use I8m290R5L0I8m2I8Camp6WW
bull Keep your game behaving like an Android application
TouchMultitouch handling
ndash With I8I9`N8R
bull take advantage of built-in gesture processing
ndash use gt0GWR96RRI6 and GWR96RRI6
ndash Most devices now support multitouch
bull determine if your device can track distinct points
ndash `Wgt2WR1FR96-F$AltA(gtltXAJA(JgtJX)
37
Input
Other Input
Trackball handling
ndash With I86TB00N8R
bull Unhandled events turn into dpad events
Motion handling
ndash With I8gt8WI6`8C4
bull Must be registered with the gt8WI68C6
bull Disable unneeded sensors especially when paused
ndash Active sensors will quickly drain the battery
38
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
OpenGL
GLSurfaceView
ndash Creates the compatible context
bull Contexts are shared between native code and Dalvik
ndash Creates a rendering thread
ndash Releases the context during onPause
ndash Not the most efficient way to multitask withOpenGL but it avoids some driver issues
When context is lost
ndash Reload resources
bull Textures
bull Buffer objects
bull Shaders
ndash Names donrsquot persist
40
Graphics
Texture Formats
Android encourages innovation in hardware
ndash Chipset vendors use several kinds of proprietary texture compression formats
ndash OpenGL ES supports multiple compressed formats none mandatory
Solutions
ndash Uncompressed Textures
ndash Use ETC1 ndash broad support in 20
bull Optimized around photographic data
bull No Alpha
ndash Use Multi-APK (coming soon)
ndash Put textures on an asset server
bull Detect support at runtime
bull Download to each device
41
Graphics
Drawing for Performance
Draw order is important
ndash Has no impact on some platforms means everything on others
ndash Draw front to back to make best use of early rejects
Use VBOs
ndash Avoid unnecessary state changes
Textures
ndash Use power of 2 sized textures
bull It can be very slow
bull On some chipsets not all address modes work
42
Graphics
Writing Compatible Shaders
Query query
ndash Make sure to query for number of attributes varying and uniforms supported
bull Varies between devices
bull Not respecting will make your application crash
bull ldquoSupportedrdquo does not mean ldquoperforms wellrdquo
Conditions
ndash Avoid as much as possible
bull if necessary put them last in the shader
ndash Use mix() clamp() etc to create the same result
discard()
ndash Avoid discard()
bull if necessary it should be last
43
Graphics
Audio Solutions
Full track audio
s 45amp026
bull Plays multiple formats with codec support
bull Plays from filesystem or from network
bull Has high latency memory and CPU usage for quick sound effects
Sound effects and clips
s gtI984ampII0
bull Plays multiple formats with codec support
bull Preloads audio files to a pool
ndash Plays them with low latency
44
Sound
Audio Solutions
Application-generated audio
s $945I6T
bull Plays PCM audio only with minimal latency
bull Useful for applications that wish to perform sound processing or mixing
OpenSLES
ndash Combines capabilities of 45amp026 and $945I6T
ndash Available only in the NDK
ndash Requires Android 23 and higher
45
Sound
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
Use native AssetManager
ndash Gingerbread and Beyond
Targeting tricky trying tasks
Troubleshooting Tips and Tricks
47
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
One JNI Context Per Thread
Threading Options
49
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
JNI Context 2
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
OR
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
If all else fails Market filters
ndash Instruction set
ndash ARMv5ARMv7
ndash GL version
ndash Platform release
ndash Use Device Availability
Tips Standing Out from the Crowd
Start Small
ndash Download assets as-needed
ndash Hook me early instead of making me wait
Use Android backuprestore service (save to the cloud)
ndash Keep my progress when I switch devices
Support multiple control schemes
ndash Trackball D-pad virtual stick
ndash Let me decide what works best
Support install-to-SD
ndash Android Market users will knock your ratings if you donrsquot
51
Tips Standing Out from the Crowd
Profiling
ndash In-game profiling to select optimal settings per-device
Social
ndash Hook into social networks
ndash Use OpenID
Build a live wallpaper
ndash Own the userrsquos home screen with stats avatars
Analytics
ndash Market and in-game
In-app payments
ndash Consider alternative monetization techniques
52
Troubleshooting Development Tools
NVIDIA Debug Manager for Eclipse
ndash Simplifies setup for native debugger under Eclipse
bull developernvidiacomtegranvidia-debug-manager-android-ndk
WinGDB
ndash Use Visual Studio to debug Android NDK applications
bull wwwwingdbcom
vs-android
ndash Native MSBuild files for Android toolchain
bull vs-androidgooglecodecom
53
Troubleshooting Performance Tools
NVIDIA PerfHUD ES
ndash developernvidiacomtegraperfhud-es
Adreno Profiler
ndash developerqualcommcomshowcaseadreno-profiler
POWERVR Insider Utilities
ndash Including PVRTrace and PVRTune
ndash wwwimgteccompowervrinsiderpowervr-utilitiesasp
54
developerandroidcomsdkndkGoogleGameDevAndroid
Feedback httpgooglNudVs
QampA
55
Whatrsquos in the Box
Toolchain
ndash Standard gcc cross-compilers
Really fancy build system
ndash Primarily written in GNU make
ndash Based on Android platform build system
Headers and libraries
ndash C and C++ runtimes
ndash Stable system interface
6
7
Application Code
Framework Classes
Runtime
Linux Kernel
JNI
Why are Headers and Libraries So Important
System Libraries
7
Application Code
Framework Classes
Runtime
Linux Kernel
JNI
Why are Headers and Libraries So Important
System Libraries
7
Application Code
Framework Classes
Runtime
Linux Kernel
JNI
Why are Headers and Libraries So Important
Your Libraries
System Libraries
7
Application Code
Framework Classes
Runtime
Linux Kernel
JNI
Why are Headers and Libraries So Important
Your Libraries
System Libraries
7
Application Code
Framework Classes
Runtime
Linux Kernel
JNI
Why are Headers and Libraries So Important
Your Libraries
System Libraries
7
Application Code
Framework Classes
Runtime
Linux Kernel
JNI
Why are Headers and Libraries So Important
Your Libraries
Stable ABI
System Libraries
8
Feature Library
C runtime libc
C++ runtime libstdc++
Math libm
Dynamic Linking libdl
Logging liblog
Zlib compression libz
OpenGL ES 11 libGLESv1_CM
OpenGL ES 20 libGLESv2
8
Feature Library
C runtime libc
C++ runtime libstdc++
Math libm
Dynamic Linking libdl
Logging liblog
Zlib compression libz
OpenGL ES 11 libGLESv1_CM
OpenGL ES 20 libGLESv2
JNI Graphics libjnigraphics
8
Feature Library
C runtime libc
C++ runtime libstdc++
Math libm
Dynamic Linking libdl
Logging liblog
Zlib compression libz
OpenGL ES 11 libGLESv1_CM
OpenGL ES 20 libGLESv2
EGL libEGL
OpenSL ES libOpenSLES
Native framework NativeActivity) libandroid
JNI Graphics libjnigraphics
What the NDK is Not
Not the end of Dalvik
Not always higher performance
Not necessarily the right choice for every game
9
Dalvik vs C++
10
C++
Flexible
Easily Extensible
Android APIAccess
AutomaticMemory
Management
Fast
Low-Level
Common onOther Platforms
How to Use the NDK
11
Installing the NDK
Download NDK from developerandroidcomsdkndk
ndash Add NDK folder to your path
ndash Install Java JDK
ndash Install Ant
Windows
ndash Install Cygwin
bull Required for debugger
bull Recommended for build scripts
12
Development Flow
13
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Development Flow Project Setup
14
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Development Flow Project Setup
14
Created by $amp($))+$)(
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Project Setup
15
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Project Setup
15
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Created Manually
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Set up project
Write makefiles
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
$ampampampltPamp$(+)+-00+1234567QL6IER$ampampAgt++++++)+05BC0DE85$ampampampJ++++++++)+4B9C$ampamp$MJ++++++++++)+61B5+61B53NS
APP_STL = gnustl_static
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
$ampampampltPamp$(+)+-00+1234567QL6IER$ampampAgt++++++)+05BC0DE85$ampampampJ++++++++)+4B9C$ampamp$MJ++++++++++)+61B5+61B53NS
APP_STL = gnustl_static
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Interface Classes
Write interface in Java
ndash Use amp) keyword
17
LTC+I1K846I54KC0DE85U
QQ+H6LL6+VI6+8R5N+05B662
L9B05+0WW+GDPXJ5B+YR84W+$R5N5R2+Z
++WRR5+Z++++gt2WR1K0I45B662-[C0DE85[7U++
++Q]]+++]+^L61+_54R`+R`+9668R+N5_+_54R`+++]+^L61+`5C`R+R`+9668R+N5_+`5C`R+++]Q+++L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7U+++L9B05+WRR5+8R5N+NI54+WRL-7U
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
PXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]LPXJ8Na+EIBER+IBEa+E58R+a+E58R+B7+Z
++E0WW+0W++-]LPXJ8N73dGRBER0WW-LPXJ8Na+IBE7U
++E1R`I4J+54++-]LPXJ8N73dGRR`I4J-+++++++++++++++++++++++++++++LPXJ8Na+0Wa+[RTm2N8RW[a+[-n7=[7U
++-]LPXJ8N73d00=I54R`I4-LPXJ8Na+IBEa+54a+PXJltA7U
Development Flow Calling Dalvik Code Within CC++
20
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Build and Deploy
gt=0Alt-amp49BCDBEFG6HI
ndash Builds C libraries and emits so files
gt)-3
ndash (or ant release)
ndash Builds Java classes apk package
gtamp=44
ndash Deploys to emulator or device
21
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdbgdb-rsp over named pipe
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdb
EclipseVS
gdb-rsp over named pipe
gdb-MI
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Important Tip
B)-36amp3)$$)J23
Bringing Your Game to Android
24
Devices Accessing Android Market
25
Android 16
Android 15
Android 23
Android 233
Android 30
Two Week Period Published May 2011
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
NativeActivity is just starting
ndash 43 of checking-in devices can utilize it
ndash For non-tablet-specific titles we can take advantage of NativeActivity without becoming incompatible
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Platform-specific Resources
Using NativeActivity Compatibly
27
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dV0WcQBII0d++++cBII0+81[8IRG58C6B64[dR69cQBII0dcQ6WI96Wd
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dR69cQBII0d++++cBII0+81[8IRG58C6B64[dV0WcQBII0dcQ6WI96Wd
Using NativeActivity Compatibly
28
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
cR5N5R2+846I54)81[Kgt$XR5N$R5N5R2[+++846I54)8B04[^BII0QRWRG58C6B64[d++c1R34R+846I54)81[846I54KLLK05B81[+++++846I54)N09[W8R5N[+Qd++++++++++++++++++++++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6d++++++++++++cQR5N5R2dcR5N5R2+846I54)81[K1I$R5N5R2[+++846I54)8B04[^BII0Q8IRG58C6B64[d++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6dcQR5N5R2d
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+W8R5N$F$Ggt+)+3$XltJXm$gtltFJgt+ )+C09R50WK+k+ LL3846I5438R5NK$JMgt+)+30GgtND+3040+300IC+30G+30846I54$gt$JJMlt$ltJgt+ )+846I548R5NLLC09$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7-00+51LI6R31I490a846I54Q8R5NLLC097
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
LTC+I1KY1L0KW88C0WU
L9B05+0WW+gt$XR5N$R5N5R2+YR84W+846I54KLLKXR5N$R5N5R2+Z
++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
LTC+I1KY1L0KW88C0WU
L9B05+0WW+1I$R5N5R2+YR84W+846I54KLLK$R5N5R2+Z++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++++++gt2WR1K0I45B662-[WE85[7U++++KKK
Key Game Components
33
Lifecycle
Graphics Sound
Input
Assets
Activity LifecycleLifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Process LifecycleLifecycle
Android keeps application processes around for as long as possible
ndash Even when the activity is closed with V585W`-7 or the back key is pressed
The foreground activity process is considered the most important
ndash It can still be killed as a last resort
Visible activities are also given high priority
ndash Backgrounded activities are considered less important
ndash Processes with no active activities are killed first
Implications of the Process LifecycleLifecycle
Be careful with static initializers
ndash Your library cannot be unloaded while your process is active
bull Donrsquot assume that your static initializers will be run when your activity is created
Be careful with threads
ndash Threads are tied to the process not the activity
bull Your threads will continue to run at reduced priority even if your activity is backgrounded or destroyed
ndash Gameplay should stop during onPause
bull It might make sense to keep certain threads running - your activity may still be visible
ndash Make sure all native code is cleaned up during onDestroy
bull Users expect that your application will no longer be active when its activity is destroyed
The Basics
Key handling
ndash Your device most likely has capacitive buttons
bull Look for complete state transitions of I8m2I_8I8m2AL
bull Avoid overriding 45WLR`m2N8R
ndash Use I8m290R5L0I8m2I8Camp6WW
bull Keep your game behaving like an Android application
TouchMultitouch handling
ndash With I8I9`N8R
bull take advantage of built-in gesture processing
ndash use gt0GWR96RRI6 and GWR96RRI6
ndash Most devices now support multitouch
bull determine if your device can track distinct points
ndash `Wgt2WR1FR96-F$AltA(gtltXAJA(JgtJX)
37
Input
Other Input
Trackball handling
ndash With I86TB00N8R
bull Unhandled events turn into dpad events
Motion handling
ndash With I8gt8WI6`8C4
bull Must be registered with the gt8WI68C6
bull Disable unneeded sensors especially when paused
ndash Active sensors will quickly drain the battery
38
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
OpenGL
GLSurfaceView
ndash Creates the compatible context
bull Contexts are shared between native code and Dalvik
ndash Creates a rendering thread
ndash Releases the context during onPause
ndash Not the most efficient way to multitask withOpenGL but it avoids some driver issues
When context is lost
ndash Reload resources
bull Textures
bull Buffer objects
bull Shaders
ndash Names donrsquot persist
40
Graphics
Texture Formats
Android encourages innovation in hardware
ndash Chipset vendors use several kinds of proprietary texture compression formats
ndash OpenGL ES supports multiple compressed formats none mandatory
Solutions
ndash Uncompressed Textures
ndash Use ETC1 ndash broad support in 20
bull Optimized around photographic data
bull No Alpha
ndash Use Multi-APK (coming soon)
ndash Put textures on an asset server
bull Detect support at runtime
bull Download to each device
41
Graphics
Drawing for Performance
Draw order is important
ndash Has no impact on some platforms means everything on others
ndash Draw front to back to make best use of early rejects
Use VBOs
ndash Avoid unnecessary state changes
Textures
ndash Use power of 2 sized textures
bull It can be very slow
bull On some chipsets not all address modes work
42
Graphics
Writing Compatible Shaders
Query query
ndash Make sure to query for number of attributes varying and uniforms supported
bull Varies between devices
bull Not respecting will make your application crash
bull ldquoSupportedrdquo does not mean ldquoperforms wellrdquo
Conditions
ndash Avoid as much as possible
bull if necessary put them last in the shader
ndash Use mix() clamp() etc to create the same result
discard()
ndash Avoid discard()
bull if necessary it should be last
43
Graphics
Audio Solutions
Full track audio
s 45amp026
bull Plays multiple formats with codec support
bull Plays from filesystem or from network
bull Has high latency memory and CPU usage for quick sound effects
Sound effects and clips
s gtI984ampII0
bull Plays multiple formats with codec support
bull Preloads audio files to a pool
ndash Plays them with low latency
44
Sound
Audio Solutions
Application-generated audio
s $945I6T
bull Plays PCM audio only with minimal latency
bull Useful for applications that wish to perform sound processing or mixing
OpenSLES
ndash Combines capabilities of 45amp026 and $945I6T
ndash Available only in the NDK
ndash Requires Android 23 and higher
45
Sound
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
Use native AssetManager
ndash Gingerbread and Beyond
Targeting tricky trying tasks
Troubleshooting Tips and Tricks
47
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
One JNI Context Per Thread
Threading Options
49
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
JNI Context 2
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
OR
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
If all else fails Market filters
ndash Instruction set
ndash ARMv5ARMv7
ndash GL version
ndash Platform release
ndash Use Device Availability
Tips Standing Out from the Crowd
Start Small
ndash Download assets as-needed
ndash Hook me early instead of making me wait
Use Android backuprestore service (save to the cloud)
ndash Keep my progress when I switch devices
Support multiple control schemes
ndash Trackball D-pad virtual stick
ndash Let me decide what works best
Support install-to-SD
ndash Android Market users will knock your ratings if you donrsquot
51
Tips Standing Out from the Crowd
Profiling
ndash In-game profiling to select optimal settings per-device
Social
ndash Hook into social networks
ndash Use OpenID
Build a live wallpaper
ndash Own the userrsquos home screen with stats avatars
Analytics
ndash Market and in-game
In-app payments
ndash Consider alternative monetization techniques
52
Troubleshooting Development Tools
NVIDIA Debug Manager for Eclipse
ndash Simplifies setup for native debugger under Eclipse
bull developernvidiacomtegranvidia-debug-manager-android-ndk
WinGDB
ndash Use Visual Studio to debug Android NDK applications
bull wwwwingdbcom
vs-android
ndash Native MSBuild files for Android toolchain
bull vs-androidgooglecodecom
53
Troubleshooting Performance Tools
NVIDIA PerfHUD ES
ndash developernvidiacomtegraperfhud-es
Adreno Profiler
ndash developerqualcommcomshowcaseadreno-profiler
POWERVR Insider Utilities
ndash Including PVRTrace and PVRTune
ndash wwwimgteccompowervrinsiderpowervr-utilitiesasp
54
developerandroidcomsdkndkGoogleGameDevAndroid
Feedback httpgooglNudVs
QampA
55
7
Application Code
Framework Classes
Runtime
Linux Kernel
JNI
Why are Headers and Libraries So Important
System Libraries
7
Application Code
Framework Classes
Runtime
Linux Kernel
JNI
Why are Headers and Libraries So Important
System Libraries
7
Application Code
Framework Classes
Runtime
Linux Kernel
JNI
Why are Headers and Libraries So Important
Your Libraries
System Libraries
7
Application Code
Framework Classes
Runtime
Linux Kernel
JNI
Why are Headers and Libraries So Important
Your Libraries
System Libraries
7
Application Code
Framework Classes
Runtime
Linux Kernel
JNI
Why are Headers and Libraries So Important
Your Libraries
System Libraries
7
Application Code
Framework Classes
Runtime
Linux Kernel
JNI
Why are Headers and Libraries So Important
Your Libraries
Stable ABI
System Libraries
8
Feature Library
C runtime libc
C++ runtime libstdc++
Math libm
Dynamic Linking libdl
Logging liblog
Zlib compression libz
OpenGL ES 11 libGLESv1_CM
OpenGL ES 20 libGLESv2
8
Feature Library
C runtime libc
C++ runtime libstdc++
Math libm
Dynamic Linking libdl
Logging liblog
Zlib compression libz
OpenGL ES 11 libGLESv1_CM
OpenGL ES 20 libGLESv2
JNI Graphics libjnigraphics
8
Feature Library
C runtime libc
C++ runtime libstdc++
Math libm
Dynamic Linking libdl
Logging liblog
Zlib compression libz
OpenGL ES 11 libGLESv1_CM
OpenGL ES 20 libGLESv2
EGL libEGL
OpenSL ES libOpenSLES
Native framework NativeActivity) libandroid
JNI Graphics libjnigraphics
What the NDK is Not
Not the end of Dalvik
Not always higher performance
Not necessarily the right choice for every game
9
Dalvik vs C++
10
C++
Flexible
Easily Extensible
Android APIAccess
AutomaticMemory
Management
Fast
Low-Level
Common onOther Platforms
How to Use the NDK
11
Installing the NDK
Download NDK from developerandroidcomsdkndk
ndash Add NDK folder to your path
ndash Install Java JDK
ndash Install Ant
Windows
ndash Install Cygwin
bull Required for debugger
bull Recommended for build scripts
12
Development Flow
13
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Development Flow Project Setup
14
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Development Flow Project Setup
14
Created by $amp($))+$)(
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Project Setup
15
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Project Setup
15
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Created Manually
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Set up project
Write makefiles
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
$ampampampltPamp$(+)+-00+1234567QL6IER$ampampAgt++++++)+05BC0DE85$ampampampJ++++++++)+4B9C$ampamp$MJ++++++++++)+61B5+61B53NS
APP_STL = gnustl_static
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
$ampampampltPamp$(+)+-00+1234567QL6IER$ampampAgt++++++)+05BC0DE85$ampampampJ++++++++)+4B9C$ampamp$MJ++++++++++)+61B5+61B53NS
APP_STL = gnustl_static
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Interface Classes
Write interface in Java
ndash Use amp) keyword
17
LTC+I1K846I54KC0DE85U
QQ+H6LL6+VI6+8R5N+05B662
L9B05+0WW+GDPXJ5B+YR84W+$R5N5R2+Z
++WRR5+Z++++gt2WR1K0I45B662-[C0DE85[7U++
++Q]]+++]+^L61+_54R`+R`+9668R+N5_+_54R`+++]+^L61+`5C`R+R`+9668R+N5_+`5C`R+++]Q+++L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7U+++L9B05+WRR5+8R5N+NI54+WRL-7U
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
PXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]LPXJ8Na+EIBER+IBEa+E58R+a+E58R+B7+Z
++E0WW+0W++-]LPXJ8N73dGRBER0WW-LPXJ8Na+IBE7U
++E1R`I4J+54++-]LPXJ8N73dGRR`I4J-+++++++++++++++++++++++++++++LPXJ8Na+0Wa+[RTm2N8RW[a+[-n7=[7U
++-]LPXJ8N73d00=I54R`I4-LPXJ8Na+IBEa+54a+PXJltA7U
Development Flow Calling Dalvik Code Within CC++
20
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Build and Deploy
gt=0Alt-amp49BCDBEFG6HI
ndash Builds C libraries and emits so files
gt)-3
ndash (or ant release)
ndash Builds Java classes apk package
gtamp=44
ndash Deploys to emulator or device
21
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdbgdb-rsp over named pipe
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdb
EclipseVS
gdb-rsp over named pipe
gdb-MI
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Important Tip
B)-36amp3)$$)J23
Bringing Your Game to Android
24
Devices Accessing Android Market
25
Android 16
Android 15
Android 23
Android 233
Android 30
Two Week Period Published May 2011
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
NativeActivity is just starting
ndash 43 of checking-in devices can utilize it
ndash For non-tablet-specific titles we can take advantage of NativeActivity without becoming incompatible
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Platform-specific Resources
Using NativeActivity Compatibly
27
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dV0WcQBII0d++++cBII0+81[8IRG58C6B64[dR69cQBII0dcQ6WI96Wd
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dR69cQBII0d++++cBII0+81[8IRG58C6B64[dV0WcQBII0dcQ6WI96Wd
Using NativeActivity Compatibly
28
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
cR5N5R2+846I54)81[Kgt$XR5N$R5N5R2[+++846I54)8B04[^BII0QRWRG58C6B64[d++c1R34R+846I54)81[846I54KLLK05B81[+++++846I54)N09[W8R5N[+Qd++++++++++++++++++++++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6d++++++++++++cQR5N5R2dcR5N5R2+846I54)81[K1I$R5N5R2[+++846I54)8B04[^BII0Q8IRG58C6B64[d++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6dcQR5N5R2d
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+W8R5N$F$Ggt+)+3$XltJXm$gtltFJgt+ )+C09R50WK+k+ LL3846I5438R5NK$JMgt+)+30GgtND+3040+300IC+30G+30846I54$gt$JJMlt$ltJgt+ )+846I548R5NLLC09$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7-00+51LI6R31I490a846I54Q8R5NLLC097
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
LTC+I1KY1L0KW88C0WU
L9B05+0WW+gt$XR5N$R5N5R2+YR84W+846I54KLLKXR5N$R5N5R2+Z
++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
LTC+I1KY1L0KW88C0WU
L9B05+0WW+1I$R5N5R2+YR84W+846I54KLLK$R5N5R2+Z++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++++++gt2WR1K0I45B662-[WE85[7U++++KKK
Key Game Components
33
Lifecycle
Graphics Sound
Input
Assets
Activity LifecycleLifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Process LifecycleLifecycle
Android keeps application processes around for as long as possible
ndash Even when the activity is closed with V585W`-7 or the back key is pressed
The foreground activity process is considered the most important
ndash It can still be killed as a last resort
Visible activities are also given high priority
ndash Backgrounded activities are considered less important
ndash Processes with no active activities are killed first
Implications of the Process LifecycleLifecycle
Be careful with static initializers
ndash Your library cannot be unloaded while your process is active
bull Donrsquot assume that your static initializers will be run when your activity is created
Be careful with threads
ndash Threads are tied to the process not the activity
bull Your threads will continue to run at reduced priority even if your activity is backgrounded or destroyed
ndash Gameplay should stop during onPause
bull It might make sense to keep certain threads running - your activity may still be visible
ndash Make sure all native code is cleaned up during onDestroy
bull Users expect that your application will no longer be active when its activity is destroyed
The Basics
Key handling
ndash Your device most likely has capacitive buttons
bull Look for complete state transitions of I8m2I_8I8m2AL
bull Avoid overriding 45WLR`m2N8R
ndash Use I8m290R5L0I8m2I8Camp6WW
bull Keep your game behaving like an Android application
TouchMultitouch handling
ndash With I8I9`N8R
bull take advantage of built-in gesture processing
ndash use gt0GWR96RRI6 and GWR96RRI6
ndash Most devices now support multitouch
bull determine if your device can track distinct points
ndash `Wgt2WR1FR96-F$AltA(gtltXAJA(JgtJX)
37
Input
Other Input
Trackball handling
ndash With I86TB00N8R
bull Unhandled events turn into dpad events
Motion handling
ndash With I8gt8WI6`8C4
bull Must be registered with the gt8WI68C6
bull Disable unneeded sensors especially when paused
ndash Active sensors will quickly drain the battery
38
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
OpenGL
GLSurfaceView
ndash Creates the compatible context
bull Contexts are shared between native code and Dalvik
ndash Creates a rendering thread
ndash Releases the context during onPause
ndash Not the most efficient way to multitask withOpenGL but it avoids some driver issues
When context is lost
ndash Reload resources
bull Textures
bull Buffer objects
bull Shaders
ndash Names donrsquot persist
40
Graphics
Texture Formats
Android encourages innovation in hardware
ndash Chipset vendors use several kinds of proprietary texture compression formats
ndash OpenGL ES supports multiple compressed formats none mandatory
Solutions
ndash Uncompressed Textures
ndash Use ETC1 ndash broad support in 20
bull Optimized around photographic data
bull No Alpha
ndash Use Multi-APK (coming soon)
ndash Put textures on an asset server
bull Detect support at runtime
bull Download to each device
41
Graphics
Drawing for Performance
Draw order is important
ndash Has no impact on some platforms means everything on others
ndash Draw front to back to make best use of early rejects
Use VBOs
ndash Avoid unnecessary state changes
Textures
ndash Use power of 2 sized textures
bull It can be very slow
bull On some chipsets not all address modes work
42
Graphics
Writing Compatible Shaders
Query query
ndash Make sure to query for number of attributes varying and uniforms supported
bull Varies between devices
bull Not respecting will make your application crash
bull ldquoSupportedrdquo does not mean ldquoperforms wellrdquo
Conditions
ndash Avoid as much as possible
bull if necessary put them last in the shader
ndash Use mix() clamp() etc to create the same result
discard()
ndash Avoid discard()
bull if necessary it should be last
43
Graphics
Audio Solutions
Full track audio
s 45amp026
bull Plays multiple formats with codec support
bull Plays from filesystem or from network
bull Has high latency memory and CPU usage for quick sound effects
Sound effects and clips
s gtI984ampII0
bull Plays multiple formats with codec support
bull Preloads audio files to a pool
ndash Plays them with low latency
44
Sound
Audio Solutions
Application-generated audio
s $945I6T
bull Plays PCM audio only with minimal latency
bull Useful for applications that wish to perform sound processing or mixing
OpenSLES
ndash Combines capabilities of 45amp026 and $945I6T
ndash Available only in the NDK
ndash Requires Android 23 and higher
45
Sound
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
Use native AssetManager
ndash Gingerbread and Beyond
Targeting tricky trying tasks
Troubleshooting Tips and Tricks
47
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
One JNI Context Per Thread
Threading Options
49
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
JNI Context 2
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
OR
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
If all else fails Market filters
ndash Instruction set
ndash ARMv5ARMv7
ndash GL version
ndash Platform release
ndash Use Device Availability
Tips Standing Out from the Crowd
Start Small
ndash Download assets as-needed
ndash Hook me early instead of making me wait
Use Android backuprestore service (save to the cloud)
ndash Keep my progress when I switch devices
Support multiple control schemes
ndash Trackball D-pad virtual stick
ndash Let me decide what works best
Support install-to-SD
ndash Android Market users will knock your ratings if you donrsquot
51
Tips Standing Out from the Crowd
Profiling
ndash In-game profiling to select optimal settings per-device
Social
ndash Hook into social networks
ndash Use OpenID
Build a live wallpaper
ndash Own the userrsquos home screen with stats avatars
Analytics
ndash Market and in-game
In-app payments
ndash Consider alternative monetization techniques
52
Troubleshooting Development Tools
NVIDIA Debug Manager for Eclipse
ndash Simplifies setup for native debugger under Eclipse
bull developernvidiacomtegranvidia-debug-manager-android-ndk
WinGDB
ndash Use Visual Studio to debug Android NDK applications
bull wwwwingdbcom
vs-android
ndash Native MSBuild files for Android toolchain
bull vs-androidgooglecodecom
53
Troubleshooting Performance Tools
NVIDIA PerfHUD ES
ndash developernvidiacomtegraperfhud-es
Adreno Profiler
ndash developerqualcommcomshowcaseadreno-profiler
POWERVR Insider Utilities
ndash Including PVRTrace and PVRTune
ndash wwwimgteccompowervrinsiderpowervr-utilitiesasp
54
developerandroidcomsdkndkGoogleGameDevAndroid
Feedback httpgooglNudVs
QampA
55
7
Application Code
Framework Classes
Runtime
Linux Kernel
JNI
Why are Headers and Libraries So Important
System Libraries
7
Application Code
Framework Classes
Runtime
Linux Kernel
JNI
Why are Headers and Libraries So Important
Your Libraries
System Libraries
7
Application Code
Framework Classes
Runtime
Linux Kernel
JNI
Why are Headers and Libraries So Important
Your Libraries
System Libraries
7
Application Code
Framework Classes
Runtime
Linux Kernel
JNI
Why are Headers and Libraries So Important
Your Libraries
System Libraries
7
Application Code
Framework Classes
Runtime
Linux Kernel
JNI
Why are Headers and Libraries So Important
Your Libraries
Stable ABI
System Libraries
8
Feature Library
C runtime libc
C++ runtime libstdc++
Math libm
Dynamic Linking libdl
Logging liblog
Zlib compression libz
OpenGL ES 11 libGLESv1_CM
OpenGL ES 20 libGLESv2
8
Feature Library
C runtime libc
C++ runtime libstdc++
Math libm
Dynamic Linking libdl
Logging liblog
Zlib compression libz
OpenGL ES 11 libGLESv1_CM
OpenGL ES 20 libGLESv2
JNI Graphics libjnigraphics
8
Feature Library
C runtime libc
C++ runtime libstdc++
Math libm
Dynamic Linking libdl
Logging liblog
Zlib compression libz
OpenGL ES 11 libGLESv1_CM
OpenGL ES 20 libGLESv2
EGL libEGL
OpenSL ES libOpenSLES
Native framework NativeActivity) libandroid
JNI Graphics libjnigraphics
What the NDK is Not
Not the end of Dalvik
Not always higher performance
Not necessarily the right choice for every game
9
Dalvik vs C++
10
C++
Flexible
Easily Extensible
Android APIAccess
AutomaticMemory
Management
Fast
Low-Level
Common onOther Platforms
How to Use the NDK
11
Installing the NDK
Download NDK from developerandroidcomsdkndk
ndash Add NDK folder to your path
ndash Install Java JDK
ndash Install Ant
Windows
ndash Install Cygwin
bull Required for debugger
bull Recommended for build scripts
12
Development Flow
13
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Development Flow Project Setup
14
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Development Flow Project Setup
14
Created by $amp($))+$)(
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Project Setup
15
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Project Setup
15
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Created Manually
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Set up project
Write makefiles
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
$ampampampltPamp$(+)+-00+1234567QL6IER$ampampAgt++++++)+05BC0DE85$ampampampJ++++++++)+4B9C$ampamp$MJ++++++++++)+61B5+61B53NS
APP_STL = gnustl_static
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
$ampampampltPamp$(+)+-00+1234567QL6IER$ampampAgt++++++)+05BC0DE85$ampampampJ++++++++)+4B9C$ampamp$MJ++++++++++)+61B5+61B53NS
APP_STL = gnustl_static
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Interface Classes
Write interface in Java
ndash Use amp) keyword
17
LTC+I1K846I54KC0DE85U
QQ+H6LL6+VI6+8R5N+05B662
L9B05+0WW+GDPXJ5B+YR84W+$R5N5R2+Z
++WRR5+Z++++gt2WR1K0I45B662-[C0DE85[7U++
++Q]]+++]+^L61+_54R`+R`+9668R+N5_+_54R`+++]+^L61+`5C`R+R`+9668R+N5_+`5C`R+++]Q+++L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7U+++L9B05+WRR5+8R5N+NI54+WRL-7U
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
PXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]LPXJ8Na+EIBER+IBEa+E58R+a+E58R+B7+Z
++E0WW+0W++-]LPXJ8N73dGRBER0WW-LPXJ8Na+IBE7U
++E1R`I4J+54++-]LPXJ8N73dGRR`I4J-+++++++++++++++++++++++++++++LPXJ8Na+0Wa+[RTm2N8RW[a+[-n7=[7U
++-]LPXJ8N73d00=I54R`I4-LPXJ8Na+IBEa+54a+PXJltA7U
Development Flow Calling Dalvik Code Within CC++
20
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Build and Deploy
gt=0Alt-amp49BCDBEFG6HI
ndash Builds C libraries and emits so files
gt)-3
ndash (or ant release)
ndash Builds Java classes apk package
gtamp=44
ndash Deploys to emulator or device
21
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdbgdb-rsp over named pipe
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdb
EclipseVS
gdb-rsp over named pipe
gdb-MI
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Important Tip
B)-36amp3)$$)J23
Bringing Your Game to Android
24
Devices Accessing Android Market
25
Android 16
Android 15
Android 23
Android 233
Android 30
Two Week Period Published May 2011
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
NativeActivity is just starting
ndash 43 of checking-in devices can utilize it
ndash For non-tablet-specific titles we can take advantage of NativeActivity without becoming incompatible
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Platform-specific Resources
Using NativeActivity Compatibly
27
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dV0WcQBII0d++++cBII0+81[8IRG58C6B64[dR69cQBII0dcQ6WI96Wd
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dR69cQBII0d++++cBII0+81[8IRG58C6B64[dV0WcQBII0dcQ6WI96Wd
Using NativeActivity Compatibly
28
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
cR5N5R2+846I54)81[Kgt$XR5N$R5N5R2[+++846I54)8B04[^BII0QRWRG58C6B64[d++c1R34R+846I54)81[846I54KLLK05B81[+++++846I54)N09[W8R5N[+Qd++++++++++++++++++++++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6d++++++++++++cQR5N5R2dcR5N5R2+846I54)81[K1I$R5N5R2[+++846I54)8B04[^BII0Q8IRG58C6B64[d++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6dcQR5N5R2d
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+W8R5N$F$Ggt+)+3$XltJXm$gtltFJgt+ )+C09R50WK+k+ LL3846I5438R5NK$JMgt+)+30GgtND+3040+300IC+30G+30846I54$gt$JJMlt$ltJgt+ )+846I548R5NLLC09$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7-00+51LI6R31I490a846I54Q8R5NLLC097
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
LTC+I1KY1L0KW88C0WU
L9B05+0WW+gt$XR5N$R5N5R2+YR84W+846I54KLLKXR5N$R5N5R2+Z
++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
LTC+I1KY1L0KW88C0WU
L9B05+0WW+1I$R5N5R2+YR84W+846I54KLLK$R5N5R2+Z++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++++++gt2WR1K0I45B662-[WE85[7U++++KKK
Key Game Components
33
Lifecycle
Graphics Sound
Input
Assets
Activity LifecycleLifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Process LifecycleLifecycle
Android keeps application processes around for as long as possible
ndash Even when the activity is closed with V585W`-7 or the back key is pressed
The foreground activity process is considered the most important
ndash It can still be killed as a last resort
Visible activities are also given high priority
ndash Backgrounded activities are considered less important
ndash Processes with no active activities are killed first
Implications of the Process LifecycleLifecycle
Be careful with static initializers
ndash Your library cannot be unloaded while your process is active
bull Donrsquot assume that your static initializers will be run when your activity is created
Be careful with threads
ndash Threads are tied to the process not the activity
bull Your threads will continue to run at reduced priority even if your activity is backgrounded or destroyed
ndash Gameplay should stop during onPause
bull It might make sense to keep certain threads running - your activity may still be visible
ndash Make sure all native code is cleaned up during onDestroy
bull Users expect that your application will no longer be active when its activity is destroyed
The Basics
Key handling
ndash Your device most likely has capacitive buttons
bull Look for complete state transitions of I8m2I_8I8m2AL
bull Avoid overriding 45WLR`m2N8R
ndash Use I8m290R5L0I8m2I8Camp6WW
bull Keep your game behaving like an Android application
TouchMultitouch handling
ndash With I8I9`N8R
bull take advantage of built-in gesture processing
ndash use gt0GWR96RRI6 and GWR96RRI6
ndash Most devices now support multitouch
bull determine if your device can track distinct points
ndash `Wgt2WR1FR96-F$AltA(gtltXAJA(JgtJX)
37
Input
Other Input
Trackball handling
ndash With I86TB00N8R
bull Unhandled events turn into dpad events
Motion handling
ndash With I8gt8WI6`8C4
bull Must be registered with the gt8WI68C6
bull Disable unneeded sensors especially when paused
ndash Active sensors will quickly drain the battery
38
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
OpenGL
GLSurfaceView
ndash Creates the compatible context
bull Contexts are shared between native code and Dalvik
ndash Creates a rendering thread
ndash Releases the context during onPause
ndash Not the most efficient way to multitask withOpenGL but it avoids some driver issues
When context is lost
ndash Reload resources
bull Textures
bull Buffer objects
bull Shaders
ndash Names donrsquot persist
40
Graphics
Texture Formats
Android encourages innovation in hardware
ndash Chipset vendors use several kinds of proprietary texture compression formats
ndash OpenGL ES supports multiple compressed formats none mandatory
Solutions
ndash Uncompressed Textures
ndash Use ETC1 ndash broad support in 20
bull Optimized around photographic data
bull No Alpha
ndash Use Multi-APK (coming soon)
ndash Put textures on an asset server
bull Detect support at runtime
bull Download to each device
41
Graphics
Drawing for Performance
Draw order is important
ndash Has no impact on some platforms means everything on others
ndash Draw front to back to make best use of early rejects
Use VBOs
ndash Avoid unnecessary state changes
Textures
ndash Use power of 2 sized textures
bull It can be very slow
bull On some chipsets not all address modes work
42
Graphics
Writing Compatible Shaders
Query query
ndash Make sure to query for number of attributes varying and uniforms supported
bull Varies between devices
bull Not respecting will make your application crash
bull ldquoSupportedrdquo does not mean ldquoperforms wellrdquo
Conditions
ndash Avoid as much as possible
bull if necessary put them last in the shader
ndash Use mix() clamp() etc to create the same result
discard()
ndash Avoid discard()
bull if necessary it should be last
43
Graphics
Audio Solutions
Full track audio
s 45amp026
bull Plays multiple formats with codec support
bull Plays from filesystem or from network
bull Has high latency memory and CPU usage for quick sound effects
Sound effects and clips
s gtI984ampII0
bull Plays multiple formats with codec support
bull Preloads audio files to a pool
ndash Plays them with low latency
44
Sound
Audio Solutions
Application-generated audio
s $945I6T
bull Plays PCM audio only with minimal latency
bull Useful for applications that wish to perform sound processing or mixing
OpenSLES
ndash Combines capabilities of 45amp026 and $945I6T
ndash Available only in the NDK
ndash Requires Android 23 and higher
45
Sound
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
Use native AssetManager
ndash Gingerbread and Beyond
Targeting tricky trying tasks
Troubleshooting Tips and Tricks
47
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
One JNI Context Per Thread
Threading Options
49
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
JNI Context 2
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
OR
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
If all else fails Market filters
ndash Instruction set
ndash ARMv5ARMv7
ndash GL version
ndash Platform release
ndash Use Device Availability
Tips Standing Out from the Crowd
Start Small
ndash Download assets as-needed
ndash Hook me early instead of making me wait
Use Android backuprestore service (save to the cloud)
ndash Keep my progress when I switch devices
Support multiple control schemes
ndash Trackball D-pad virtual stick
ndash Let me decide what works best
Support install-to-SD
ndash Android Market users will knock your ratings if you donrsquot
51
Tips Standing Out from the Crowd
Profiling
ndash In-game profiling to select optimal settings per-device
Social
ndash Hook into social networks
ndash Use OpenID
Build a live wallpaper
ndash Own the userrsquos home screen with stats avatars
Analytics
ndash Market and in-game
In-app payments
ndash Consider alternative monetization techniques
52
Troubleshooting Development Tools
NVIDIA Debug Manager for Eclipse
ndash Simplifies setup for native debugger under Eclipse
bull developernvidiacomtegranvidia-debug-manager-android-ndk
WinGDB
ndash Use Visual Studio to debug Android NDK applications
bull wwwwingdbcom
vs-android
ndash Native MSBuild files for Android toolchain
bull vs-androidgooglecodecom
53
Troubleshooting Performance Tools
NVIDIA PerfHUD ES
ndash developernvidiacomtegraperfhud-es
Adreno Profiler
ndash developerqualcommcomshowcaseadreno-profiler
POWERVR Insider Utilities
ndash Including PVRTrace and PVRTune
ndash wwwimgteccompowervrinsiderpowervr-utilitiesasp
54
developerandroidcomsdkndkGoogleGameDevAndroid
Feedback httpgooglNudVs
QampA
55
7
Application Code
Framework Classes
Runtime
Linux Kernel
JNI
Why are Headers and Libraries So Important
Your Libraries
System Libraries
7
Application Code
Framework Classes
Runtime
Linux Kernel
JNI
Why are Headers and Libraries So Important
Your Libraries
System Libraries
7
Application Code
Framework Classes
Runtime
Linux Kernel
JNI
Why are Headers and Libraries So Important
Your Libraries
System Libraries
7
Application Code
Framework Classes
Runtime
Linux Kernel
JNI
Why are Headers and Libraries So Important
Your Libraries
Stable ABI
System Libraries
8
Feature Library
C runtime libc
C++ runtime libstdc++
Math libm
Dynamic Linking libdl
Logging liblog
Zlib compression libz
OpenGL ES 11 libGLESv1_CM
OpenGL ES 20 libGLESv2
8
Feature Library
C runtime libc
C++ runtime libstdc++
Math libm
Dynamic Linking libdl
Logging liblog
Zlib compression libz
OpenGL ES 11 libGLESv1_CM
OpenGL ES 20 libGLESv2
JNI Graphics libjnigraphics
8
Feature Library
C runtime libc
C++ runtime libstdc++
Math libm
Dynamic Linking libdl
Logging liblog
Zlib compression libz
OpenGL ES 11 libGLESv1_CM
OpenGL ES 20 libGLESv2
EGL libEGL
OpenSL ES libOpenSLES
Native framework NativeActivity) libandroid
JNI Graphics libjnigraphics
What the NDK is Not
Not the end of Dalvik
Not always higher performance
Not necessarily the right choice for every game
9
Dalvik vs C++
10
C++
Flexible
Easily Extensible
Android APIAccess
AutomaticMemory
Management
Fast
Low-Level
Common onOther Platforms
How to Use the NDK
11
Installing the NDK
Download NDK from developerandroidcomsdkndk
ndash Add NDK folder to your path
ndash Install Java JDK
ndash Install Ant
Windows
ndash Install Cygwin
bull Required for debugger
bull Recommended for build scripts
12
Development Flow
13
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Development Flow Project Setup
14
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Development Flow Project Setup
14
Created by $amp($))+$)(
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Project Setup
15
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Project Setup
15
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Created Manually
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Set up project
Write makefiles
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
$ampampampltPamp$(+)+-00+1234567QL6IER$ampampAgt++++++)+05BC0DE85$ampampampJ++++++++)+4B9C$ampamp$MJ++++++++++)+61B5+61B53NS
APP_STL = gnustl_static
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
$ampampampltPamp$(+)+-00+1234567QL6IER$ampampAgt++++++)+05BC0DE85$ampampampJ++++++++)+4B9C$ampamp$MJ++++++++++)+61B5+61B53NS
APP_STL = gnustl_static
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Interface Classes
Write interface in Java
ndash Use amp) keyword
17
LTC+I1K846I54KC0DE85U
QQ+H6LL6+VI6+8R5N+05B662
L9B05+0WW+GDPXJ5B+YR84W+$R5N5R2+Z
++WRR5+Z++++gt2WR1K0I45B662-[C0DE85[7U++
++Q]]+++]+^L61+_54R`+R`+9668R+N5_+_54R`+++]+^L61+`5C`R+R`+9668R+N5_+`5C`R+++]Q+++L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7U+++L9B05+WRR5+8R5N+NI54+WRL-7U
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
PXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]LPXJ8Na+EIBER+IBEa+E58R+a+E58R+B7+Z
++E0WW+0W++-]LPXJ8N73dGRBER0WW-LPXJ8Na+IBE7U
++E1R`I4J+54++-]LPXJ8N73dGRR`I4J-+++++++++++++++++++++++++++++LPXJ8Na+0Wa+[RTm2N8RW[a+[-n7=[7U
++-]LPXJ8N73d00=I54R`I4-LPXJ8Na+IBEa+54a+PXJltA7U
Development Flow Calling Dalvik Code Within CC++
20
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Build and Deploy
gt=0Alt-amp49BCDBEFG6HI
ndash Builds C libraries and emits so files
gt)-3
ndash (or ant release)
ndash Builds Java classes apk package
gtamp=44
ndash Deploys to emulator or device
21
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdbgdb-rsp over named pipe
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdb
EclipseVS
gdb-rsp over named pipe
gdb-MI
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Important Tip
B)-36amp3)$$)J23
Bringing Your Game to Android
24
Devices Accessing Android Market
25
Android 16
Android 15
Android 23
Android 233
Android 30
Two Week Period Published May 2011
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
NativeActivity is just starting
ndash 43 of checking-in devices can utilize it
ndash For non-tablet-specific titles we can take advantage of NativeActivity without becoming incompatible
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Platform-specific Resources
Using NativeActivity Compatibly
27
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dV0WcQBII0d++++cBII0+81[8IRG58C6B64[dR69cQBII0dcQ6WI96Wd
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dR69cQBII0d++++cBII0+81[8IRG58C6B64[dV0WcQBII0dcQ6WI96Wd
Using NativeActivity Compatibly
28
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
cR5N5R2+846I54)81[Kgt$XR5N$R5N5R2[+++846I54)8B04[^BII0QRWRG58C6B64[d++c1R34R+846I54)81[846I54KLLK05B81[+++++846I54)N09[W8R5N[+Qd++++++++++++++++++++++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6d++++++++++++cQR5N5R2dcR5N5R2+846I54)81[K1I$R5N5R2[+++846I54)8B04[^BII0Q8IRG58C6B64[d++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6dcQR5N5R2d
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+W8R5N$F$Ggt+)+3$XltJXm$gtltFJgt+ )+C09R50WK+k+ LL3846I5438R5NK$JMgt+)+30GgtND+3040+300IC+30G+30846I54$gt$JJMlt$ltJgt+ )+846I548R5NLLC09$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7-00+51LI6R31I490a846I54Q8R5NLLC097
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
LTC+I1KY1L0KW88C0WU
L9B05+0WW+gt$XR5N$R5N5R2+YR84W+846I54KLLKXR5N$R5N5R2+Z
++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
LTC+I1KY1L0KW88C0WU
L9B05+0WW+1I$R5N5R2+YR84W+846I54KLLK$R5N5R2+Z++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++++++gt2WR1K0I45B662-[WE85[7U++++KKK
Key Game Components
33
Lifecycle
Graphics Sound
Input
Assets
Activity LifecycleLifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Process LifecycleLifecycle
Android keeps application processes around for as long as possible
ndash Even when the activity is closed with V585W`-7 or the back key is pressed
The foreground activity process is considered the most important
ndash It can still be killed as a last resort
Visible activities are also given high priority
ndash Backgrounded activities are considered less important
ndash Processes with no active activities are killed first
Implications of the Process LifecycleLifecycle
Be careful with static initializers
ndash Your library cannot be unloaded while your process is active
bull Donrsquot assume that your static initializers will be run when your activity is created
Be careful with threads
ndash Threads are tied to the process not the activity
bull Your threads will continue to run at reduced priority even if your activity is backgrounded or destroyed
ndash Gameplay should stop during onPause
bull It might make sense to keep certain threads running - your activity may still be visible
ndash Make sure all native code is cleaned up during onDestroy
bull Users expect that your application will no longer be active when its activity is destroyed
The Basics
Key handling
ndash Your device most likely has capacitive buttons
bull Look for complete state transitions of I8m2I_8I8m2AL
bull Avoid overriding 45WLR`m2N8R
ndash Use I8m290R5L0I8m2I8Camp6WW
bull Keep your game behaving like an Android application
TouchMultitouch handling
ndash With I8I9`N8R
bull take advantage of built-in gesture processing
ndash use gt0GWR96RRI6 and GWR96RRI6
ndash Most devices now support multitouch
bull determine if your device can track distinct points
ndash `Wgt2WR1FR96-F$AltA(gtltXAJA(JgtJX)
37
Input
Other Input
Trackball handling
ndash With I86TB00N8R
bull Unhandled events turn into dpad events
Motion handling
ndash With I8gt8WI6`8C4
bull Must be registered with the gt8WI68C6
bull Disable unneeded sensors especially when paused
ndash Active sensors will quickly drain the battery
38
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
OpenGL
GLSurfaceView
ndash Creates the compatible context
bull Contexts are shared between native code and Dalvik
ndash Creates a rendering thread
ndash Releases the context during onPause
ndash Not the most efficient way to multitask withOpenGL but it avoids some driver issues
When context is lost
ndash Reload resources
bull Textures
bull Buffer objects
bull Shaders
ndash Names donrsquot persist
40
Graphics
Texture Formats
Android encourages innovation in hardware
ndash Chipset vendors use several kinds of proprietary texture compression formats
ndash OpenGL ES supports multiple compressed formats none mandatory
Solutions
ndash Uncompressed Textures
ndash Use ETC1 ndash broad support in 20
bull Optimized around photographic data
bull No Alpha
ndash Use Multi-APK (coming soon)
ndash Put textures on an asset server
bull Detect support at runtime
bull Download to each device
41
Graphics
Drawing for Performance
Draw order is important
ndash Has no impact on some platforms means everything on others
ndash Draw front to back to make best use of early rejects
Use VBOs
ndash Avoid unnecessary state changes
Textures
ndash Use power of 2 sized textures
bull It can be very slow
bull On some chipsets not all address modes work
42
Graphics
Writing Compatible Shaders
Query query
ndash Make sure to query for number of attributes varying and uniforms supported
bull Varies between devices
bull Not respecting will make your application crash
bull ldquoSupportedrdquo does not mean ldquoperforms wellrdquo
Conditions
ndash Avoid as much as possible
bull if necessary put them last in the shader
ndash Use mix() clamp() etc to create the same result
discard()
ndash Avoid discard()
bull if necessary it should be last
43
Graphics
Audio Solutions
Full track audio
s 45amp026
bull Plays multiple formats with codec support
bull Plays from filesystem or from network
bull Has high latency memory and CPU usage for quick sound effects
Sound effects and clips
s gtI984ampII0
bull Plays multiple formats with codec support
bull Preloads audio files to a pool
ndash Plays them with low latency
44
Sound
Audio Solutions
Application-generated audio
s $945I6T
bull Plays PCM audio only with minimal latency
bull Useful for applications that wish to perform sound processing or mixing
OpenSLES
ndash Combines capabilities of 45amp026 and $945I6T
ndash Available only in the NDK
ndash Requires Android 23 and higher
45
Sound
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
Use native AssetManager
ndash Gingerbread and Beyond
Targeting tricky trying tasks
Troubleshooting Tips and Tricks
47
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
One JNI Context Per Thread
Threading Options
49
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
JNI Context 2
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
OR
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
If all else fails Market filters
ndash Instruction set
ndash ARMv5ARMv7
ndash GL version
ndash Platform release
ndash Use Device Availability
Tips Standing Out from the Crowd
Start Small
ndash Download assets as-needed
ndash Hook me early instead of making me wait
Use Android backuprestore service (save to the cloud)
ndash Keep my progress when I switch devices
Support multiple control schemes
ndash Trackball D-pad virtual stick
ndash Let me decide what works best
Support install-to-SD
ndash Android Market users will knock your ratings if you donrsquot
51
Tips Standing Out from the Crowd
Profiling
ndash In-game profiling to select optimal settings per-device
Social
ndash Hook into social networks
ndash Use OpenID
Build a live wallpaper
ndash Own the userrsquos home screen with stats avatars
Analytics
ndash Market and in-game
In-app payments
ndash Consider alternative monetization techniques
52
Troubleshooting Development Tools
NVIDIA Debug Manager for Eclipse
ndash Simplifies setup for native debugger under Eclipse
bull developernvidiacomtegranvidia-debug-manager-android-ndk
WinGDB
ndash Use Visual Studio to debug Android NDK applications
bull wwwwingdbcom
vs-android
ndash Native MSBuild files for Android toolchain
bull vs-androidgooglecodecom
53
Troubleshooting Performance Tools
NVIDIA PerfHUD ES
ndash developernvidiacomtegraperfhud-es
Adreno Profiler
ndash developerqualcommcomshowcaseadreno-profiler
POWERVR Insider Utilities
ndash Including PVRTrace and PVRTune
ndash wwwimgteccompowervrinsiderpowervr-utilitiesasp
54
developerandroidcomsdkndkGoogleGameDevAndroid
Feedback httpgooglNudVs
QampA
55
7
Application Code
Framework Classes
Runtime
Linux Kernel
JNI
Why are Headers and Libraries So Important
Your Libraries
System Libraries
7
Application Code
Framework Classes
Runtime
Linux Kernel
JNI
Why are Headers and Libraries So Important
Your Libraries
System Libraries
7
Application Code
Framework Classes
Runtime
Linux Kernel
JNI
Why are Headers and Libraries So Important
Your Libraries
Stable ABI
System Libraries
8
Feature Library
C runtime libc
C++ runtime libstdc++
Math libm
Dynamic Linking libdl
Logging liblog
Zlib compression libz
OpenGL ES 11 libGLESv1_CM
OpenGL ES 20 libGLESv2
8
Feature Library
C runtime libc
C++ runtime libstdc++
Math libm
Dynamic Linking libdl
Logging liblog
Zlib compression libz
OpenGL ES 11 libGLESv1_CM
OpenGL ES 20 libGLESv2
JNI Graphics libjnigraphics
8
Feature Library
C runtime libc
C++ runtime libstdc++
Math libm
Dynamic Linking libdl
Logging liblog
Zlib compression libz
OpenGL ES 11 libGLESv1_CM
OpenGL ES 20 libGLESv2
EGL libEGL
OpenSL ES libOpenSLES
Native framework NativeActivity) libandroid
JNI Graphics libjnigraphics
What the NDK is Not
Not the end of Dalvik
Not always higher performance
Not necessarily the right choice for every game
9
Dalvik vs C++
10
C++
Flexible
Easily Extensible
Android APIAccess
AutomaticMemory
Management
Fast
Low-Level
Common onOther Platforms
How to Use the NDK
11
Installing the NDK
Download NDK from developerandroidcomsdkndk
ndash Add NDK folder to your path
ndash Install Java JDK
ndash Install Ant
Windows
ndash Install Cygwin
bull Required for debugger
bull Recommended for build scripts
12
Development Flow
13
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Development Flow Project Setup
14
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Development Flow Project Setup
14
Created by $amp($))+$)(
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Project Setup
15
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Project Setup
15
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Created Manually
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Set up project
Write makefiles
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
$ampampampltPamp$(+)+-00+1234567QL6IER$ampampAgt++++++)+05BC0DE85$ampampampJ++++++++)+4B9C$ampamp$MJ++++++++++)+61B5+61B53NS
APP_STL = gnustl_static
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
$ampampampltPamp$(+)+-00+1234567QL6IER$ampampAgt++++++)+05BC0DE85$ampampampJ++++++++)+4B9C$ampamp$MJ++++++++++)+61B5+61B53NS
APP_STL = gnustl_static
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Interface Classes
Write interface in Java
ndash Use amp) keyword
17
LTC+I1K846I54KC0DE85U
QQ+H6LL6+VI6+8R5N+05B662
L9B05+0WW+GDPXJ5B+YR84W+$R5N5R2+Z
++WRR5+Z++++gt2WR1K0I45B662-[C0DE85[7U++
++Q]]+++]+^L61+_54R`+R`+9668R+N5_+_54R`+++]+^L61+`5C`R+R`+9668R+N5_+`5C`R+++]Q+++L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7U+++L9B05+WRR5+8R5N+NI54+WRL-7U
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
PXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]LPXJ8Na+EIBER+IBEa+E58R+a+E58R+B7+Z
++E0WW+0W++-]LPXJ8N73dGRBER0WW-LPXJ8Na+IBE7U
++E1R`I4J+54++-]LPXJ8N73dGRR`I4J-+++++++++++++++++++++++++++++LPXJ8Na+0Wa+[RTm2N8RW[a+[-n7=[7U
++-]LPXJ8N73d00=I54R`I4-LPXJ8Na+IBEa+54a+PXJltA7U
Development Flow Calling Dalvik Code Within CC++
20
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Build and Deploy
gt=0Alt-amp49BCDBEFG6HI
ndash Builds C libraries and emits so files
gt)-3
ndash (or ant release)
ndash Builds Java classes apk package
gtamp=44
ndash Deploys to emulator or device
21
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdbgdb-rsp over named pipe
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdb
EclipseVS
gdb-rsp over named pipe
gdb-MI
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Important Tip
B)-36amp3)$$)J23
Bringing Your Game to Android
24
Devices Accessing Android Market
25
Android 16
Android 15
Android 23
Android 233
Android 30
Two Week Period Published May 2011
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
NativeActivity is just starting
ndash 43 of checking-in devices can utilize it
ndash For non-tablet-specific titles we can take advantage of NativeActivity without becoming incompatible
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Platform-specific Resources
Using NativeActivity Compatibly
27
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dV0WcQBII0d++++cBII0+81[8IRG58C6B64[dR69cQBII0dcQ6WI96Wd
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dR69cQBII0d++++cBII0+81[8IRG58C6B64[dV0WcQBII0dcQ6WI96Wd
Using NativeActivity Compatibly
28
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
cR5N5R2+846I54)81[Kgt$XR5N$R5N5R2[+++846I54)8B04[^BII0QRWRG58C6B64[d++c1R34R+846I54)81[846I54KLLK05B81[+++++846I54)N09[W8R5N[+Qd++++++++++++++++++++++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6d++++++++++++cQR5N5R2dcR5N5R2+846I54)81[K1I$R5N5R2[+++846I54)8B04[^BII0Q8IRG58C6B64[d++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6dcQR5N5R2d
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+W8R5N$F$Ggt+)+3$XltJXm$gtltFJgt+ )+C09R50WK+k+ LL3846I5438R5NK$JMgt+)+30GgtND+3040+300IC+30G+30846I54$gt$JJMlt$ltJgt+ )+846I548R5NLLC09$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7-00+51LI6R31I490a846I54Q8R5NLLC097
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
LTC+I1KY1L0KW88C0WU
L9B05+0WW+gt$XR5N$R5N5R2+YR84W+846I54KLLKXR5N$R5N5R2+Z
++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
LTC+I1KY1L0KW88C0WU
L9B05+0WW+1I$R5N5R2+YR84W+846I54KLLK$R5N5R2+Z++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++++++gt2WR1K0I45B662-[WE85[7U++++KKK
Key Game Components
33
Lifecycle
Graphics Sound
Input
Assets
Activity LifecycleLifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Process LifecycleLifecycle
Android keeps application processes around for as long as possible
ndash Even when the activity is closed with V585W`-7 or the back key is pressed
The foreground activity process is considered the most important
ndash It can still be killed as a last resort
Visible activities are also given high priority
ndash Backgrounded activities are considered less important
ndash Processes with no active activities are killed first
Implications of the Process LifecycleLifecycle
Be careful with static initializers
ndash Your library cannot be unloaded while your process is active
bull Donrsquot assume that your static initializers will be run when your activity is created
Be careful with threads
ndash Threads are tied to the process not the activity
bull Your threads will continue to run at reduced priority even if your activity is backgrounded or destroyed
ndash Gameplay should stop during onPause
bull It might make sense to keep certain threads running - your activity may still be visible
ndash Make sure all native code is cleaned up during onDestroy
bull Users expect that your application will no longer be active when its activity is destroyed
The Basics
Key handling
ndash Your device most likely has capacitive buttons
bull Look for complete state transitions of I8m2I_8I8m2AL
bull Avoid overriding 45WLR`m2N8R
ndash Use I8m290R5L0I8m2I8Camp6WW
bull Keep your game behaving like an Android application
TouchMultitouch handling
ndash With I8I9`N8R
bull take advantage of built-in gesture processing
ndash use gt0GWR96RRI6 and GWR96RRI6
ndash Most devices now support multitouch
bull determine if your device can track distinct points
ndash `Wgt2WR1FR96-F$AltA(gtltXAJA(JgtJX)
37
Input
Other Input
Trackball handling
ndash With I86TB00N8R
bull Unhandled events turn into dpad events
Motion handling
ndash With I8gt8WI6`8C4
bull Must be registered with the gt8WI68C6
bull Disable unneeded sensors especially when paused
ndash Active sensors will quickly drain the battery
38
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
OpenGL
GLSurfaceView
ndash Creates the compatible context
bull Contexts are shared between native code and Dalvik
ndash Creates a rendering thread
ndash Releases the context during onPause
ndash Not the most efficient way to multitask withOpenGL but it avoids some driver issues
When context is lost
ndash Reload resources
bull Textures
bull Buffer objects
bull Shaders
ndash Names donrsquot persist
40
Graphics
Texture Formats
Android encourages innovation in hardware
ndash Chipset vendors use several kinds of proprietary texture compression formats
ndash OpenGL ES supports multiple compressed formats none mandatory
Solutions
ndash Uncompressed Textures
ndash Use ETC1 ndash broad support in 20
bull Optimized around photographic data
bull No Alpha
ndash Use Multi-APK (coming soon)
ndash Put textures on an asset server
bull Detect support at runtime
bull Download to each device
41
Graphics
Drawing for Performance
Draw order is important
ndash Has no impact on some platforms means everything on others
ndash Draw front to back to make best use of early rejects
Use VBOs
ndash Avoid unnecessary state changes
Textures
ndash Use power of 2 sized textures
bull It can be very slow
bull On some chipsets not all address modes work
42
Graphics
Writing Compatible Shaders
Query query
ndash Make sure to query for number of attributes varying and uniforms supported
bull Varies between devices
bull Not respecting will make your application crash
bull ldquoSupportedrdquo does not mean ldquoperforms wellrdquo
Conditions
ndash Avoid as much as possible
bull if necessary put them last in the shader
ndash Use mix() clamp() etc to create the same result
discard()
ndash Avoid discard()
bull if necessary it should be last
43
Graphics
Audio Solutions
Full track audio
s 45amp026
bull Plays multiple formats with codec support
bull Plays from filesystem or from network
bull Has high latency memory and CPU usage for quick sound effects
Sound effects and clips
s gtI984ampII0
bull Plays multiple formats with codec support
bull Preloads audio files to a pool
ndash Plays them with low latency
44
Sound
Audio Solutions
Application-generated audio
s $945I6T
bull Plays PCM audio only with minimal latency
bull Useful for applications that wish to perform sound processing or mixing
OpenSLES
ndash Combines capabilities of 45amp026 and $945I6T
ndash Available only in the NDK
ndash Requires Android 23 and higher
45
Sound
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
Use native AssetManager
ndash Gingerbread and Beyond
Targeting tricky trying tasks
Troubleshooting Tips and Tricks
47
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
One JNI Context Per Thread
Threading Options
49
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
JNI Context 2
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
OR
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
If all else fails Market filters
ndash Instruction set
ndash ARMv5ARMv7
ndash GL version
ndash Platform release
ndash Use Device Availability
Tips Standing Out from the Crowd
Start Small
ndash Download assets as-needed
ndash Hook me early instead of making me wait
Use Android backuprestore service (save to the cloud)
ndash Keep my progress when I switch devices
Support multiple control schemes
ndash Trackball D-pad virtual stick
ndash Let me decide what works best
Support install-to-SD
ndash Android Market users will knock your ratings if you donrsquot
51
Tips Standing Out from the Crowd
Profiling
ndash In-game profiling to select optimal settings per-device
Social
ndash Hook into social networks
ndash Use OpenID
Build a live wallpaper
ndash Own the userrsquos home screen with stats avatars
Analytics
ndash Market and in-game
In-app payments
ndash Consider alternative monetization techniques
52
Troubleshooting Development Tools
NVIDIA Debug Manager for Eclipse
ndash Simplifies setup for native debugger under Eclipse
bull developernvidiacomtegranvidia-debug-manager-android-ndk
WinGDB
ndash Use Visual Studio to debug Android NDK applications
bull wwwwingdbcom
vs-android
ndash Native MSBuild files for Android toolchain
bull vs-androidgooglecodecom
53
Troubleshooting Performance Tools
NVIDIA PerfHUD ES
ndash developernvidiacomtegraperfhud-es
Adreno Profiler
ndash developerqualcommcomshowcaseadreno-profiler
POWERVR Insider Utilities
ndash Including PVRTrace and PVRTune
ndash wwwimgteccompowervrinsiderpowervr-utilitiesasp
54
developerandroidcomsdkndkGoogleGameDevAndroid
Feedback httpgooglNudVs
QampA
55
7
Application Code
Framework Classes
Runtime
Linux Kernel
JNI
Why are Headers and Libraries So Important
Your Libraries
System Libraries
7
Application Code
Framework Classes
Runtime
Linux Kernel
JNI
Why are Headers and Libraries So Important
Your Libraries
Stable ABI
System Libraries
8
Feature Library
C runtime libc
C++ runtime libstdc++
Math libm
Dynamic Linking libdl
Logging liblog
Zlib compression libz
OpenGL ES 11 libGLESv1_CM
OpenGL ES 20 libGLESv2
8
Feature Library
C runtime libc
C++ runtime libstdc++
Math libm
Dynamic Linking libdl
Logging liblog
Zlib compression libz
OpenGL ES 11 libGLESv1_CM
OpenGL ES 20 libGLESv2
JNI Graphics libjnigraphics
8
Feature Library
C runtime libc
C++ runtime libstdc++
Math libm
Dynamic Linking libdl
Logging liblog
Zlib compression libz
OpenGL ES 11 libGLESv1_CM
OpenGL ES 20 libGLESv2
EGL libEGL
OpenSL ES libOpenSLES
Native framework NativeActivity) libandroid
JNI Graphics libjnigraphics
What the NDK is Not
Not the end of Dalvik
Not always higher performance
Not necessarily the right choice for every game
9
Dalvik vs C++
10
C++
Flexible
Easily Extensible
Android APIAccess
AutomaticMemory
Management
Fast
Low-Level
Common onOther Platforms
How to Use the NDK
11
Installing the NDK
Download NDK from developerandroidcomsdkndk
ndash Add NDK folder to your path
ndash Install Java JDK
ndash Install Ant
Windows
ndash Install Cygwin
bull Required for debugger
bull Recommended for build scripts
12
Development Flow
13
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Development Flow Project Setup
14
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Development Flow Project Setup
14
Created by $amp($))+$)(
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Project Setup
15
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Project Setup
15
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Created Manually
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Set up project
Write makefiles
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
$ampampampltPamp$(+)+-00+1234567QL6IER$ampampAgt++++++)+05BC0DE85$ampampampJ++++++++)+4B9C$ampamp$MJ++++++++++)+61B5+61B53NS
APP_STL = gnustl_static
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
$ampampampltPamp$(+)+-00+1234567QL6IER$ampampAgt++++++)+05BC0DE85$ampampampJ++++++++)+4B9C$ampamp$MJ++++++++++)+61B5+61B53NS
APP_STL = gnustl_static
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Interface Classes
Write interface in Java
ndash Use amp) keyword
17
LTC+I1K846I54KC0DE85U
QQ+H6LL6+VI6+8R5N+05B662
L9B05+0WW+GDPXJ5B+YR84W+$R5N5R2+Z
++WRR5+Z++++gt2WR1K0I45B662-[C0DE85[7U++
++Q]]+++]+^L61+_54R`+R`+9668R+N5_+_54R`+++]+^L61+`5C`R+R`+9668R+N5_+`5C`R+++]Q+++L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7U+++L9B05+WRR5+8R5N+NI54+WRL-7U
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
PXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]LPXJ8Na+EIBER+IBEa+E58R+a+E58R+B7+Z
++E0WW+0W++-]LPXJ8N73dGRBER0WW-LPXJ8Na+IBE7U
++E1R`I4J+54++-]LPXJ8N73dGRR`I4J-+++++++++++++++++++++++++++++LPXJ8Na+0Wa+[RTm2N8RW[a+[-n7=[7U
++-]LPXJ8N73d00=I54R`I4-LPXJ8Na+IBEa+54a+PXJltA7U
Development Flow Calling Dalvik Code Within CC++
20
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Build and Deploy
gt=0Alt-amp49BCDBEFG6HI
ndash Builds C libraries and emits so files
gt)-3
ndash (or ant release)
ndash Builds Java classes apk package
gtamp=44
ndash Deploys to emulator or device
21
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdbgdb-rsp over named pipe
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdb
EclipseVS
gdb-rsp over named pipe
gdb-MI
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Important Tip
B)-36amp3)$$)J23
Bringing Your Game to Android
24
Devices Accessing Android Market
25
Android 16
Android 15
Android 23
Android 233
Android 30
Two Week Period Published May 2011
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
NativeActivity is just starting
ndash 43 of checking-in devices can utilize it
ndash For non-tablet-specific titles we can take advantage of NativeActivity without becoming incompatible
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Platform-specific Resources
Using NativeActivity Compatibly
27
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dV0WcQBII0d++++cBII0+81[8IRG58C6B64[dR69cQBII0dcQ6WI96Wd
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dR69cQBII0d++++cBII0+81[8IRG58C6B64[dV0WcQBII0dcQ6WI96Wd
Using NativeActivity Compatibly
28
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
cR5N5R2+846I54)81[Kgt$XR5N$R5N5R2[+++846I54)8B04[^BII0QRWRG58C6B64[d++c1R34R+846I54)81[846I54KLLK05B81[+++++846I54)N09[W8R5N[+Qd++++++++++++++++++++++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6d++++++++++++cQR5N5R2dcR5N5R2+846I54)81[K1I$R5N5R2[+++846I54)8B04[^BII0Q8IRG58C6B64[d++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6dcQR5N5R2d
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+W8R5N$F$Ggt+)+3$XltJXm$gtltFJgt+ )+C09R50WK+k+ LL3846I5438R5NK$JMgt+)+30GgtND+3040+300IC+30G+30846I54$gt$JJMlt$ltJgt+ )+846I548R5NLLC09$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7-00+51LI6R31I490a846I54Q8R5NLLC097
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
LTC+I1KY1L0KW88C0WU
L9B05+0WW+gt$XR5N$R5N5R2+YR84W+846I54KLLKXR5N$R5N5R2+Z
++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
LTC+I1KY1L0KW88C0WU
L9B05+0WW+1I$R5N5R2+YR84W+846I54KLLK$R5N5R2+Z++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++++++gt2WR1K0I45B662-[WE85[7U++++KKK
Key Game Components
33
Lifecycle
Graphics Sound
Input
Assets
Activity LifecycleLifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Process LifecycleLifecycle
Android keeps application processes around for as long as possible
ndash Even when the activity is closed with V585W`-7 or the back key is pressed
The foreground activity process is considered the most important
ndash It can still be killed as a last resort
Visible activities are also given high priority
ndash Backgrounded activities are considered less important
ndash Processes with no active activities are killed first
Implications of the Process LifecycleLifecycle
Be careful with static initializers
ndash Your library cannot be unloaded while your process is active
bull Donrsquot assume that your static initializers will be run when your activity is created
Be careful with threads
ndash Threads are tied to the process not the activity
bull Your threads will continue to run at reduced priority even if your activity is backgrounded or destroyed
ndash Gameplay should stop during onPause
bull It might make sense to keep certain threads running - your activity may still be visible
ndash Make sure all native code is cleaned up during onDestroy
bull Users expect that your application will no longer be active when its activity is destroyed
The Basics
Key handling
ndash Your device most likely has capacitive buttons
bull Look for complete state transitions of I8m2I_8I8m2AL
bull Avoid overriding 45WLR`m2N8R
ndash Use I8m290R5L0I8m2I8Camp6WW
bull Keep your game behaving like an Android application
TouchMultitouch handling
ndash With I8I9`N8R
bull take advantage of built-in gesture processing
ndash use gt0GWR96RRI6 and GWR96RRI6
ndash Most devices now support multitouch
bull determine if your device can track distinct points
ndash `Wgt2WR1FR96-F$AltA(gtltXAJA(JgtJX)
37
Input
Other Input
Trackball handling
ndash With I86TB00N8R
bull Unhandled events turn into dpad events
Motion handling
ndash With I8gt8WI6`8C4
bull Must be registered with the gt8WI68C6
bull Disable unneeded sensors especially when paused
ndash Active sensors will quickly drain the battery
38
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
OpenGL
GLSurfaceView
ndash Creates the compatible context
bull Contexts are shared between native code and Dalvik
ndash Creates a rendering thread
ndash Releases the context during onPause
ndash Not the most efficient way to multitask withOpenGL but it avoids some driver issues
When context is lost
ndash Reload resources
bull Textures
bull Buffer objects
bull Shaders
ndash Names donrsquot persist
40
Graphics
Texture Formats
Android encourages innovation in hardware
ndash Chipset vendors use several kinds of proprietary texture compression formats
ndash OpenGL ES supports multiple compressed formats none mandatory
Solutions
ndash Uncompressed Textures
ndash Use ETC1 ndash broad support in 20
bull Optimized around photographic data
bull No Alpha
ndash Use Multi-APK (coming soon)
ndash Put textures on an asset server
bull Detect support at runtime
bull Download to each device
41
Graphics
Drawing for Performance
Draw order is important
ndash Has no impact on some platforms means everything on others
ndash Draw front to back to make best use of early rejects
Use VBOs
ndash Avoid unnecessary state changes
Textures
ndash Use power of 2 sized textures
bull It can be very slow
bull On some chipsets not all address modes work
42
Graphics
Writing Compatible Shaders
Query query
ndash Make sure to query for number of attributes varying and uniforms supported
bull Varies between devices
bull Not respecting will make your application crash
bull ldquoSupportedrdquo does not mean ldquoperforms wellrdquo
Conditions
ndash Avoid as much as possible
bull if necessary put them last in the shader
ndash Use mix() clamp() etc to create the same result
discard()
ndash Avoid discard()
bull if necessary it should be last
43
Graphics
Audio Solutions
Full track audio
s 45amp026
bull Plays multiple formats with codec support
bull Plays from filesystem or from network
bull Has high latency memory and CPU usage for quick sound effects
Sound effects and clips
s gtI984ampII0
bull Plays multiple formats with codec support
bull Preloads audio files to a pool
ndash Plays them with low latency
44
Sound
Audio Solutions
Application-generated audio
s $945I6T
bull Plays PCM audio only with minimal latency
bull Useful for applications that wish to perform sound processing or mixing
OpenSLES
ndash Combines capabilities of 45amp026 and $945I6T
ndash Available only in the NDK
ndash Requires Android 23 and higher
45
Sound
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
Use native AssetManager
ndash Gingerbread and Beyond
Targeting tricky trying tasks
Troubleshooting Tips and Tricks
47
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
One JNI Context Per Thread
Threading Options
49
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
JNI Context 2
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
OR
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
If all else fails Market filters
ndash Instruction set
ndash ARMv5ARMv7
ndash GL version
ndash Platform release
ndash Use Device Availability
Tips Standing Out from the Crowd
Start Small
ndash Download assets as-needed
ndash Hook me early instead of making me wait
Use Android backuprestore service (save to the cloud)
ndash Keep my progress when I switch devices
Support multiple control schemes
ndash Trackball D-pad virtual stick
ndash Let me decide what works best
Support install-to-SD
ndash Android Market users will knock your ratings if you donrsquot
51
Tips Standing Out from the Crowd
Profiling
ndash In-game profiling to select optimal settings per-device
Social
ndash Hook into social networks
ndash Use OpenID
Build a live wallpaper
ndash Own the userrsquos home screen with stats avatars
Analytics
ndash Market and in-game
In-app payments
ndash Consider alternative monetization techniques
52
Troubleshooting Development Tools
NVIDIA Debug Manager for Eclipse
ndash Simplifies setup for native debugger under Eclipse
bull developernvidiacomtegranvidia-debug-manager-android-ndk
WinGDB
ndash Use Visual Studio to debug Android NDK applications
bull wwwwingdbcom
vs-android
ndash Native MSBuild files for Android toolchain
bull vs-androidgooglecodecom
53
Troubleshooting Performance Tools
NVIDIA PerfHUD ES
ndash developernvidiacomtegraperfhud-es
Adreno Profiler
ndash developerqualcommcomshowcaseadreno-profiler
POWERVR Insider Utilities
ndash Including PVRTrace and PVRTune
ndash wwwimgteccompowervrinsiderpowervr-utilitiesasp
54
developerandroidcomsdkndkGoogleGameDevAndroid
Feedback httpgooglNudVs
QampA
55
7
Application Code
Framework Classes
Runtime
Linux Kernel
JNI
Why are Headers and Libraries So Important
Your Libraries
Stable ABI
System Libraries
8
Feature Library
C runtime libc
C++ runtime libstdc++
Math libm
Dynamic Linking libdl
Logging liblog
Zlib compression libz
OpenGL ES 11 libGLESv1_CM
OpenGL ES 20 libGLESv2
8
Feature Library
C runtime libc
C++ runtime libstdc++
Math libm
Dynamic Linking libdl
Logging liblog
Zlib compression libz
OpenGL ES 11 libGLESv1_CM
OpenGL ES 20 libGLESv2
JNI Graphics libjnigraphics
8
Feature Library
C runtime libc
C++ runtime libstdc++
Math libm
Dynamic Linking libdl
Logging liblog
Zlib compression libz
OpenGL ES 11 libGLESv1_CM
OpenGL ES 20 libGLESv2
EGL libEGL
OpenSL ES libOpenSLES
Native framework NativeActivity) libandroid
JNI Graphics libjnigraphics
What the NDK is Not
Not the end of Dalvik
Not always higher performance
Not necessarily the right choice for every game
9
Dalvik vs C++
10
C++
Flexible
Easily Extensible
Android APIAccess
AutomaticMemory
Management
Fast
Low-Level
Common onOther Platforms
How to Use the NDK
11
Installing the NDK
Download NDK from developerandroidcomsdkndk
ndash Add NDK folder to your path
ndash Install Java JDK
ndash Install Ant
Windows
ndash Install Cygwin
bull Required for debugger
bull Recommended for build scripts
12
Development Flow
13
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Development Flow Project Setup
14
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Development Flow Project Setup
14
Created by $amp($))+$)(
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Project Setup
15
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Project Setup
15
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Created Manually
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Set up project
Write makefiles
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
$ampampampltPamp$(+)+-00+1234567QL6IER$ampampAgt++++++)+05BC0DE85$ampampampJ++++++++)+4B9C$ampamp$MJ++++++++++)+61B5+61B53NS
APP_STL = gnustl_static
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
$ampampampltPamp$(+)+-00+1234567QL6IER$ampampAgt++++++)+05BC0DE85$ampampampJ++++++++)+4B9C$ampamp$MJ++++++++++)+61B5+61B53NS
APP_STL = gnustl_static
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Interface Classes
Write interface in Java
ndash Use amp) keyword
17
LTC+I1K846I54KC0DE85U
QQ+H6LL6+VI6+8R5N+05B662
L9B05+0WW+GDPXJ5B+YR84W+$R5N5R2+Z
++WRR5+Z++++gt2WR1K0I45B662-[C0DE85[7U++
++Q]]+++]+^L61+_54R`+R`+9668R+N5_+_54R`+++]+^L61+`5C`R+R`+9668R+N5_+`5C`R+++]Q+++L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7U+++L9B05+WRR5+8R5N+NI54+WRL-7U
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
PXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]LPXJ8Na+EIBER+IBEa+E58R+a+E58R+B7+Z
++E0WW+0W++-]LPXJ8N73dGRBER0WW-LPXJ8Na+IBE7U
++E1R`I4J+54++-]LPXJ8N73dGRR`I4J-+++++++++++++++++++++++++++++LPXJ8Na+0Wa+[RTm2N8RW[a+[-n7=[7U
++-]LPXJ8N73d00=I54R`I4-LPXJ8Na+IBEa+54a+PXJltA7U
Development Flow Calling Dalvik Code Within CC++
20
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Build and Deploy
gt=0Alt-amp49BCDBEFG6HI
ndash Builds C libraries and emits so files
gt)-3
ndash (or ant release)
ndash Builds Java classes apk package
gtamp=44
ndash Deploys to emulator or device
21
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdbgdb-rsp over named pipe
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdb
EclipseVS
gdb-rsp over named pipe
gdb-MI
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Important Tip
B)-36amp3)$$)J23
Bringing Your Game to Android
24
Devices Accessing Android Market
25
Android 16
Android 15
Android 23
Android 233
Android 30
Two Week Period Published May 2011
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
NativeActivity is just starting
ndash 43 of checking-in devices can utilize it
ndash For non-tablet-specific titles we can take advantage of NativeActivity without becoming incompatible
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Platform-specific Resources
Using NativeActivity Compatibly
27
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dV0WcQBII0d++++cBII0+81[8IRG58C6B64[dR69cQBII0dcQ6WI96Wd
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dR69cQBII0d++++cBII0+81[8IRG58C6B64[dV0WcQBII0dcQ6WI96Wd
Using NativeActivity Compatibly
28
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
cR5N5R2+846I54)81[Kgt$XR5N$R5N5R2[+++846I54)8B04[^BII0QRWRG58C6B64[d++c1R34R+846I54)81[846I54KLLK05B81[+++++846I54)N09[W8R5N[+Qd++++++++++++++++++++++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6d++++++++++++cQR5N5R2dcR5N5R2+846I54)81[K1I$R5N5R2[+++846I54)8B04[^BII0Q8IRG58C6B64[d++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6dcQR5N5R2d
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+W8R5N$F$Ggt+)+3$XltJXm$gtltFJgt+ )+C09R50WK+k+ LL3846I5438R5NK$JMgt+)+30GgtND+3040+300IC+30G+30846I54$gt$JJMlt$ltJgt+ )+846I548R5NLLC09$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7-00+51LI6R31I490a846I54Q8R5NLLC097
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
LTC+I1KY1L0KW88C0WU
L9B05+0WW+gt$XR5N$R5N5R2+YR84W+846I54KLLKXR5N$R5N5R2+Z
++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
LTC+I1KY1L0KW88C0WU
L9B05+0WW+1I$R5N5R2+YR84W+846I54KLLK$R5N5R2+Z++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++++++gt2WR1K0I45B662-[WE85[7U++++KKK
Key Game Components
33
Lifecycle
Graphics Sound
Input
Assets
Activity LifecycleLifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Process LifecycleLifecycle
Android keeps application processes around for as long as possible
ndash Even when the activity is closed with V585W`-7 or the back key is pressed
The foreground activity process is considered the most important
ndash It can still be killed as a last resort
Visible activities are also given high priority
ndash Backgrounded activities are considered less important
ndash Processes with no active activities are killed first
Implications of the Process LifecycleLifecycle
Be careful with static initializers
ndash Your library cannot be unloaded while your process is active
bull Donrsquot assume that your static initializers will be run when your activity is created
Be careful with threads
ndash Threads are tied to the process not the activity
bull Your threads will continue to run at reduced priority even if your activity is backgrounded or destroyed
ndash Gameplay should stop during onPause
bull It might make sense to keep certain threads running - your activity may still be visible
ndash Make sure all native code is cleaned up during onDestroy
bull Users expect that your application will no longer be active when its activity is destroyed
The Basics
Key handling
ndash Your device most likely has capacitive buttons
bull Look for complete state transitions of I8m2I_8I8m2AL
bull Avoid overriding 45WLR`m2N8R
ndash Use I8m290R5L0I8m2I8Camp6WW
bull Keep your game behaving like an Android application
TouchMultitouch handling
ndash With I8I9`N8R
bull take advantage of built-in gesture processing
ndash use gt0GWR96RRI6 and GWR96RRI6
ndash Most devices now support multitouch
bull determine if your device can track distinct points
ndash `Wgt2WR1FR96-F$AltA(gtltXAJA(JgtJX)
37
Input
Other Input
Trackball handling
ndash With I86TB00N8R
bull Unhandled events turn into dpad events
Motion handling
ndash With I8gt8WI6`8C4
bull Must be registered with the gt8WI68C6
bull Disable unneeded sensors especially when paused
ndash Active sensors will quickly drain the battery
38
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
OpenGL
GLSurfaceView
ndash Creates the compatible context
bull Contexts are shared between native code and Dalvik
ndash Creates a rendering thread
ndash Releases the context during onPause
ndash Not the most efficient way to multitask withOpenGL but it avoids some driver issues
When context is lost
ndash Reload resources
bull Textures
bull Buffer objects
bull Shaders
ndash Names donrsquot persist
40
Graphics
Texture Formats
Android encourages innovation in hardware
ndash Chipset vendors use several kinds of proprietary texture compression formats
ndash OpenGL ES supports multiple compressed formats none mandatory
Solutions
ndash Uncompressed Textures
ndash Use ETC1 ndash broad support in 20
bull Optimized around photographic data
bull No Alpha
ndash Use Multi-APK (coming soon)
ndash Put textures on an asset server
bull Detect support at runtime
bull Download to each device
41
Graphics
Drawing for Performance
Draw order is important
ndash Has no impact on some platforms means everything on others
ndash Draw front to back to make best use of early rejects
Use VBOs
ndash Avoid unnecessary state changes
Textures
ndash Use power of 2 sized textures
bull It can be very slow
bull On some chipsets not all address modes work
42
Graphics
Writing Compatible Shaders
Query query
ndash Make sure to query for number of attributes varying and uniforms supported
bull Varies between devices
bull Not respecting will make your application crash
bull ldquoSupportedrdquo does not mean ldquoperforms wellrdquo
Conditions
ndash Avoid as much as possible
bull if necessary put them last in the shader
ndash Use mix() clamp() etc to create the same result
discard()
ndash Avoid discard()
bull if necessary it should be last
43
Graphics
Audio Solutions
Full track audio
s 45amp026
bull Plays multiple formats with codec support
bull Plays from filesystem or from network
bull Has high latency memory and CPU usage for quick sound effects
Sound effects and clips
s gtI984ampII0
bull Plays multiple formats with codec support
bull Preloads audio files to a pool
ndash Plays them with low latency
44
Sound
Audio Solutions
Application-generated audio
s $945I6T
bull Plays PCM audio only with minimal latency
bull Useful for applications that wish to perform sound processing or mixing
OpenSLES
ndash Combines capabilities of 45amp026 and $945I6T
ndash Available only in the NDK
ndash Requires Android 23 and higher
45
Sound
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
Use native AssetManager
ndash Gingerbread and Beyond
Targeting tricky trying tasks
Troubleshooting Tips and Tricks
47
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
One JNI Context Per Thread
Threading Options
49
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
JNI Context 2
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
OR
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
If all else fails Market filters
ndash Instruction set
ndash ARMv5ARMv7
ndash GL version
ndash Platform release
ndash Use Device Availability
Tips Standing Out from the Crowd
Start Small
ndash Download assets as-needed
ndash Hook me early instead of making me wait
Use Android backuprestore service (save to the cloud)
ndash Keep my progress when I switch devices
Support multiple control schemes
ndash Trackball D-pad virtual stick
ndash Let me decide what works best
Support install-to-SD
ndash Android Market users will knock your ratings if you donrsquot
51
Tips Standing Out from the Crowd
Profiling
ndash In-game profiling to select optimal settings per-device
Social
ndash Hook into social networks
ndash Use OpenID
Build a live wallpaper
ndash Own the userrsquos home screen with stats avatars
Analytics
ndash Market and in-game
In-app payments
ndash Consider alternative monetization techniques
52
Troubleshooting Development Tools
NVIDIA Debug Manager for Eclipse
ndash Simplifies setup for native debugger under Eclipse
bull developernvidiacomtegranvidia-debug-manager-android-ndk
WinGDB
ndash Use Visual Studio to debug Android NDK applications
bull wwwwingdbcom
vs-android
ndash Native MSBuild files for Android toolchain
bull vs-androidgooglecodecom
53
Troubleshooting Performance Tools
NVIDIA PerfHUD ES
ndash developernvidiacomtegraperfhud-es
Adreno Profiler
ndash developerqualcommcomshowcaseadreno-profiler
POWERVR Insider Utilities
ndash Including PVRTrace and PVRTune
ndash wwwimgteccompowervrinsiderpowervr-utilitiesasp
54
developerandroidcomsdkndkGoogleGameDevAndroid
Feedback httpgooglNudVs
QampA
55
8
Feature Library
C runtime libc
C++ runtime libstdc++
Math libm
Dynamic Linking libdl
Logging liblog
Zlib compression libz
OpenGL ES 11 libGLESv1_CM
OpenGL ES 20 libGLESv2
8
Feature Library
C runtime libc
C++ runtime libstdc++
Math libm
Dynamic Linking libdl
Logging liblog
Zlib compression libz
OpenGL ES 11 libGLESv1_CM
OpenGL ES 20 libGLESv2
JNI Graphics libjnigraphics
8
Feature Library
C runtime libc
C++ runtime libstdc++
Math libm
Dynamic Linking libdl
Logging liblog
Zlib compression libz
OpenGL ES 11 libGLESv1_CM
OpenGL ES 20 libGLESv2
EGL libEGL
OpenSL ES libOpenSLES
Native framework NativeActivity) libandroid
JNI Graphics libjnigraphics
What the NDK is Not
Not the end of Dalvik
Not always higher performance
Not necessarily the right choice for every game
9
Dalvik vs C++
10
C++
Flexible
Easily Extensible
Android APIAccess
AutomaticMemory
Management
Fast
Low-Level
Common onOther Platforms
How to Use the NDK
11
Installing the NDK
Download NDK from developerandroidcomsdkndk
ndash Add NDK folder to your path
ndash Install Java JDK
ndash Install Ant
Windows
ndash Install Cygwin
bull Required for debugger
bull Recommended for build scripts
12
Development Flow
13
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Development Flow Project Setup
14
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Development Flow Project Setup
14
Created by $amp($))+$)(
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Project Setup
15
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Project Setup
15
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Created Manually
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Set up project
Write makefiles
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
$ampampampltPamp$(+)+-00+1234567QL6IER$ampampAgt++++++)+05BC0DE85$ampampampJ++++++++)+4B9C$ampamp$MJ++++++++++)+61B5+61B53NS
APP_STL = gnustl_static
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
$ampampampltPamp$(+)+-00+1234567QL6IER$ampampAgt++++++)+05BC0DE85$ampampampJ++++++++)+4B9C$ampamp$MJ++++++++++)+61B5+61B53NS
APP_STL = gnustl_static
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Interface Classes
Write interface in Java
ndash Use amp) keyword
17
LTC+I1K846I54KC0DE85U
QQ+H6LL6+VI6+8R5N+05B662
L9B05+0WW+GDPXJ5B+YR84W+$R5N5R2+Z
++WRR5+Z++++gt2WR1K0I45B662-[C0DE85[7U++
++Q]]+++]+^L61+_54R`+R`+9668R+N5_+_54R`+++]+^L61+`5C`R+R`+9668R+N5_+`5C`R+++]Q+++L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7U+++L9B05+WRR5+8R5N+NI54+WRL-7U
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
PXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]LPXJ8Na+EIBER+IBEa+E58R+a+E58R+B7+Z
++E0WW+0W++-]LPXJ8N73dGRBER0WW-LPXJ8Na+IBE7U
++E1R`I4J+54++-]LPXJ8N73dGRR`I4J-+++++++++++++++++++++++++++++LPXJ8Na+0Wa+[RTm2N8RW[a+[-n7=[7U
++-]LPXJ8N73d00=I54R`I4-LPXJ8Na+IBEa+54a+PXJltA7U
Development Flow Calling Dalvik Code Within CC++
20
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Build and Deploy
gt=0Alt-amp49BCDBEFG6HI
ndash Builds C libraries and emits so files
gt)-3
ndash (or ant release)
ndash Builds Java classes apk package
gtamp=44
ndash Deploys to emulator or device
21
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdbgdb-rsp over named pipe
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdb
EclipseVS
gdb-rsp over named pipe
gdb-MI
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Important Tip
B)-36amp3)$$)J23
Bringing Your Game to Android
24
Devices Accessing Android Market
25
Android 16
Android 15
Android 23
Android 233
Android 30
Two Week Period Published May 2011
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
NativeActivity is just starting
ndash 43 of checking-in devices can utilize it
ndash For non-tablet-specific titles we can take advantage of NativeActivity without becoming incompatible
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Platform-specific Resources
Using NativeActivity Compatibly
27
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dV0WcQBII0d++++cBII0+81[8IRG58C6B64[dR69cQBII0dcQ6WI96Wd
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dR69cQBII0d++++cBII0+81[8IRG58C6B64[dV0WcQBII0dcQ6WI96Wd
Using NativeActivity Compatibly
28
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
cR5N5R2+846I54)81[Kgt$XR5N$R5N5R2[+++846I54)8B04[^BII0QRWRG58C6B64[d++c1R34R+846I54)81[846I54KLLK05B81[+++++846I54)N09[W8R5N[+Qd++++++++++++++++++++++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6d++++++++++++cQR5N5R2dcR5N5R2+846I54)81[K1I$R5N5R2[+++846I54)8B04[^BII0Q8IRG58C6B64[d++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6dcQR5N5R2d
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+W8R5N$F$Ggt+)+3$XltJXm$gtltFJgt+ )+C09R50WK+k+ LL3846I5438R5NK$JMgt+)+30GgtND+3040+300IC+30G+30846I54$gt$JJMlt$ltJgt+ )+846I548R5NLLC09$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7-00+51LI6R31I490a846I54Q8R5NLLC097
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
LTC+I1KY1L0KW88C0WU
L9B05+0WW+gt$XR5N$R5N5R2+YR84W+846I54KLLKXR5N$R5N5R2+Z
++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
LTC+I1KY1L0KW88C0WU
L9B05+0WW+1I$R5N5R2+YR84W+846I54KLLK$R5N5R2+Z++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++++++gt2WR1K0I45B662-[WE85[7U++++KKK
Key Game Components
33
Lifecycle
Graphics Sound
Input
Assets
Activity LifecycleLifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Process LifecycleLifecycle
Android keeps application processes around for as long as possible
ndash Even when the activity is closed with V585W`-7 or the back key is pressed
The foreground activity process is considered the most important
ndash It can still be killed as a last resort
Visible activities are also given high priority
ndash Backgrounded activities are considered less important
ndash Processes with no active activities are killed first
Implications of the Process LifecycleLifecycle
Be careful with static initializers
ndash Your library cannot be unloaded while your process is active
bull Donrsquot assume that your static initializers will be run when your activity is created
Be careful with threads
ndash Threads are tied to the process not the activity
bull Your threads will continue to run at reduced priority even if your activity is backgrounded or destroyed
ndash Gameplay should stop during onPause
bull It might make sense to keep certain threads running - your activity may still be visible
ndash Make sure all native code is cleaned up during onDestroy
bull Users expect that your application will no longer be active when its activity is destroyed
The Basics
Key handling
ndash Your device most likely has capacitive buttons
bull Look for complete state transitions of I8m2I_8I8m2AL
bull Avoid overriding 45WLR`m2N8R
ndash Use I8m290R5L0I8m2I8Camp6WW
bull Keep your game behaving like an Android application
TouchMultitouch handling
ndash With I8I9`N8R
bull take advantage of built-in gesture processing
ndash use gt0GWR96RRI6 and GWR96RRI6
ndash Most devices now support multitouch
bull determine if your device can track distinct points
ndash `Wgt2WR1FR96-F$AltA(gtltXAJA(JgtJX)
37
Input
Other Input
Trackball handling
ndash With I86TB00N8R
bull Unhandled events turn into dpad events
Motion handling
ndash With I8gt8WI6`8C4
bull Must be registered with the gt8WI68C6
bull Disable unneeded sensors especially when paused
ndash Active sensors will quickly drain the battery
38
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
OpenGL
GLSurfaceView
ndash Creates the compatible context
bull Contexts are shared between native code and Dalvik
ndash Creates a rendering thread
ndash Releases the context during onPause
ndash Not the most efficient way to multitask withOpenGL but it avoids some driver issues
When context is lost
ndash Reload resources
bull Textures
bull Buffer objects
bull Shaders
ndash Names donrsquot persist
40
Graphics
Texture Formats
Android encourages innovation in hardware
ndash Chipset vendors use several kinds of proprietary texture compression formats
ndash OpenGL ES supports multiple compressed formats none mandatory
Solutions
ndash Uncompressed Textures
ndash Use ETC1 ndash broad support in 20
bull Optimized around photographic data
bull No Alpha
ndash Use Multi-APK (coming soon)
ndash Put textures on an asset server
bull Detect support at runtime
bull Download to each device
41
Graphics
Drawing for Performance
Draw order is important
ndash Has no impact on some platforms means everything on others
ndash Draw front to back to make best use of early rejects
Use VBOs
ndash Avoid unnecessary state changes
Textures
ndash Use power of 2 sized textures
bull It can be very slow
bull On some chipsets not all address modes work
42
Graphics
Writing Compatible Shaders
Query query
ndash Make sure to query for number of attributes varying and uniforms supported
bull Varies between devices
bull Not respecting will make your application crash
bull ldquoSupportedrdquo does not mean ldquoperforms wellrdquo
Conditions
ndash Avoid as much as possible
bull if necessary put them last in the shader
ndash Use mix() clamp() etc to create the same result
discard()
ndash Avoid discard()
bull if necessary it should be last
43
Graphics
Audio Solutions
Full track audio
s 45amp026
bull Plays multiple formats with codec support
bull Plays from filesystem or from network
bull Has high latency memory and CPU usage for quick sound effects
Sound effects and clips
s gtI984ampII0
bull Plays multiple formats with codec support
bull Preloads audio files to a pool
ndash Plays them with low latency
44
Sound
Audio Solutions
Application-generated audio
s $945I6T
bull Plays PCM audio only with minimal latency
bull Useful for applications that wish to perform sound processing or mixing
OpenSLES
ndash Combines capabilities of 45amp026 and $945I6T
ndash Available only in the NDK
ndash Requires Android 23 and higher
45
Sound
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
Use native AssetManager
ndash Gingerbread and Beyond
Targeting tricky trying tasks
Troubleshooting Tips and Tricks
47
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
One JNI Context Per Thread
Threading Options
49
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
JNI Context 2
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
OR
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
If all else fails Market filters
ndash Instruction set
ndash ARMv5ARMv7
ndash GL version
ndash Platform release
ndash Use Device Availability
Tips Standing Out from the Crowd
Start Small
ndash Download assets as-needed
ndash Hook me early instead of making me wait
Use Android backuprestore service (save to the cloud)
ndash Keep my progress when I switch devices
Support multiple control schemes
ndash Trackball D-pad virtual stick
ndash Let me decide what works best
Support install-to-SD
ndash Android Market users will knock your ratings if you donrsquot
51
Tips Standing Out from the Crowd
Profiling
ndash In-game profiling to select optimal settings per-device
Social
ndash Hook into social networks
ndash Use OpenID
Build a live wallpaper
ndash Own the userrsquos home screen with stats avatars
Analytics
ndash Market and in-game
In-app payments
ndash Consider alternative monetization techniques
52
Troubleshooting Development Tools
NVIDIA Debug Manager for Eclipse
ndash Simplifies setup for native debugger under Eclipse
bull developernvidiacomtegranvidia-debug-manager-android-ndk
WinGDB
ndash Use Visual Studio to debug Android NDK applications
bull wwwwingdbcom
vs-android
ndash Native MSBuild files for Android toolchain
bull vs-androidgooglecodecom
53
Troubleshooting Performance Tools
NVIDIA PerfHUD ES
ndash developernvidiacomtegraperfhud-es
Adreno Profiler
ndash developerqualcommcomshowcaseadreno-profiler
POWERVR Insider Utilities
ndash Including PVRTrace and PVRTune
ndash wwwimgteccompowervrinsiderpowervr-utilitiesasp
54
developerandroidcomsdkndkGoogleGameDevAndroid
Feedback httpgooglNudVs
QampA
55
8
Feature Library
C runtime libc
C++ runtime libstdc++
Math libm
Dynamic Linking libdl
Logging liblog
Zlib compression libz
OpenGL ES 11 libGLESv1_CM
OpenGL ES 20 libGLESv2
JNI Graphics libjnigraphics
8
Feature Library
C runtime libc
C++ runtime libstdc++
Math libm
Dynamic Linking libdl
Logging liblog
Zlib compression libz
OpenGL ES 11 libGLESv1_CM
OpenGL ES 20 libGLESv2
EGL libEGL
OpenSL ES libOpenSLES
Native framework NativeActivity) libandroid
JNI Graphics libjnigraphics
What the NDK is Not
Not the end of Dalvik
Not always higher performance
Not necessarily the right choice for every game
9
Dalvik vs C++
10
C++
Flexible
Easily Extensible
Android APIAccess
AutomaticMemory
Management
Fast
Low-Level
Common onOther Platforms
How to Use the NDK
11
Installing the NDK
Download NDK from developerandroidcomsdkndk
ndash Add NDK folder to your path
ndash Install Java JDK
ndash Install Ant
Windows
ndash Install Cygwin
bull Required for debugger
bull Recommended for build scripts
12
Development Flow
13
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Development Flow Project Setup
14
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Development Flow Project Setup
14
Created by $amp($))+$)(
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Project Setup
15
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Project Setup
15
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Created Manually
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Set up project
Write makefiles
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
$ampampampltPamp$(+)+-00+1234567QL6IER$ampampAgt++++++)+05BC0DE85$ampampampJ++++++++)+4B9C$ampamp$MJ++++++++++)+61B5+61B53NS
APP_STL = gnustl_static
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
$ampampampltPamp$(+)+-00+1234567QL6IER$ampampAgt++++++)+05BC0DE85$ampampampJ++++++++)+4B9C$ampamp$MJ++++++++++)+61B5+61B53NS
APP_STL = gnustl_static
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Interface Classes
Write interface in Java
ndash Use amp) keyword
17
LTC+I1K846I54KC0DE85U
QQ+H6LL6+VI6+8R5N+05B662
L9B05+0WW+GDPXJ5B+YR84W+$R5N5R2+Z
++WRR5+Z++++gt2WR1K0I45B662-[C0DE85[7U++
++Q]]+++]+^L61+_54R`+R`+9668R+N5_+_54R`+++]+^L61+`5C`R+R`+9668R+N5_+`5C`R+++]Q+++L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7U+++L9B05+WRR5+8R5N+NI54+WRL-7U
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
PXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]LPXJ8Na+EIBER+IBEa+E58R+a+E58R+B7+Z
++E0WW+0W++-]LPXJ8N73dGRBER0WW-LPXJ8Na+IBE7U
++E1R`I4J+54++-]LPXJ8N73dGRR`I4J-+++++++++++++++++++++++++++++LPXJ8Na+0Wa+[RTm2N8RW[a+[-n7=[7U
++-]LPXJ8N73d00=I54R`I4-LPXJ8Na+IBEa+54a+PXJltA7U
Development Flow Calling Dalvik Code Within CC++
20
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Build and Deploy
gt=0Alt-amp49BCDBEFG6HI
ndash Builds C libraries and emits so files
gt)-3
ndash (or ant release)
ndash Builds Java classes apk package
gtamp=44
ndash Deploys to emulator or device
21
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdbgdb-rsp over named pipe
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdb
EclipseVS
gdb-rsp over named pipe
gdb-MI
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Important Tip
B)-36amp3)$$)J23
Bringing Your Game to Android
24
Devices Accessing Android Market
25
Android 16
Android 15
Android 23
Android 233
Android 30
Two Week Period Published May 2011
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
NativeActivity is just starting
ndash 43 of checking-in devices can utilize it
ndash For non-tablet-specific titles we can take advantage of NativeActivity without becoming incompatible
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Platform-specific Resources
Using NativeActivity Compatibly
27
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dV0WcQBII0d++++cBII0+81[8IRG58C6B64[dR69cQBII0dcQ6WI96Wd
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dR69cQBII0d++++cBII0+81[8IRG58C6B64[dV0WcQBII0dcQ6WI96Wd
Using NativeActivity Compatibly
28
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
cR5N5R2+846I54)81[Kgt$XR5N$R5N5R2[+++846I54)8B04[^BII0QRWRG58C6B64[d++c1R34R+846I54)81[846I54KLLK05B81[+++++846I54)N09[W8R5N[+Qd++++++++++++++++++++++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6d++++++++++++cQR5N5R2dcR5N5R2+846I54)81[K1I$R5N5R2[+++846I54)8B04[^BII0Q8IRG58C6B64[d++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6dcQR5N5R2d
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+W8R5N$F$Ggt+)+3$XltJXm$gtltFJgt+ )+C09R50WK+k+ LL3846I5438R5NK$JMgt+)+30GgtND+3040+300IC+30G+30846I54$gt$JJMlt$ltJgt+ )+846I548R5NLLC09$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7-00+51LI6R31I490a846I54Q8R5NLLC097
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
LTC+I1KY1L0KW88C0WU
L9B05+0WW+gt$XR5N$R5N5R2+YR84W+846I54KLLKXR5N$R5N5R2+Z
++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
LTC+I1KY1L0KW88C0WU
L9B05+0WW+1I$R5N5R2+YR84W+846I54KLLK$R5N5R2+Z++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++++++gt2WR1K0I45B662-[WE85[7U++++KKK
Key Game Components
33
Lifecycle
Graphics Sound
Input
Assets
Activity LifecycleLifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Process LifecycleLifecycle
Android keeps application processes around for as long as possible
ndash Even when the activity is closed with V585W`-7 or the back key is pressed
The foreground activity process is considered the most important
ndash It can still be killed as a last resort
Visible activities are also given high priority
ndash Backgrounded activities are considered less important
ndash Processes with no active activities are killed first
Implications of the Process LifecycleLifecycle
Be careful with static initializers
ndash Your library cannot be unloaded while your process is active
bull Donrsquot assume that your static initializers will be run when your activity is created
Be careful with threads
ndash Threads are tied to the process not the activity
bull Your threads will continue to run at reduced priority even if your activity is backgrounded or destroyed
ndash Gameplay should stop during onPause
bull It might make sense to keep certain threads running - your activity may still be visible
ndash Make sure all native code is cleaned up during onDestroy
bull Users expect that your application will no longer be active when its activity is destroyed
The Basics
Key handling
ndash Your device most likely has capacitive buttons
bull Look for complete state transitions of I8m2I_8I8m2AL
bull Avoid overriding 45WLR`m2N8R
ndash Use I8m290R5L0I8m2I8Camp6WW
bull Keep your game behaving like an Android application
TouchMultitouch handling
ndash With I8I9`N8R
bull take advantage of built-in gesture processing
ndash use gt0GWR96RRI6 and GWR96RRI6
ndash Most devices now support multitouch
bull determine if your device can track distinct points
ndash `Wgt2WR1FR96-F$AltA(gtltXAJA(JgtJX)
37
Input
Other Input
Trackball handling
ndash With I86TB00N8R
bull Unhandled events turn into dpad events
Motion handling
ndash With I8gt8WI6`8C4
bull Must be registered with the gt8WI68C6
bull Disable unneeded sensors especially when paused
ndash Active sensors will quickly drain the battery
38
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
OpenGL
GLSurfaceView
ndash Creates the compatible context
bull Contexts are shared between native code and Dalvik
ndash Creates a rendering thread
ndash Releases the context during onPause
ndash Not the most efficient way to multitask withOpenGL but it avoids some driver issues
When context is lost
ndash Reload resources
bull Textures
bull Buffer objects
bull Shaders
ndash Names donrsquot persist
40
Graphics
Texture Formats
Android encourages innovation in hardware
ndash Chipset vendors use several kinds of proprietary texture compression formats
ndash OpenGL ES supports multiple compressed formats none mandatory
Solutions
ndash Uncompressed Textures
ndash Use ETC1 ndash broad support in 20
bull Optimized around photographic data
bull No Alpha
ndash Use Multi-APK (coming soon)
ndash Put textures on an asset server
bull Detect support at runtime
bull Download to each device
41
Graphics
Drawing for Performance
Draw order is important
ndash Has no impact on some platforms means everything on others
ndash Draw front to back to make best use of early rejects
Use VBOs
ndash Avoid unnecessary state changes
Textures
ndash Use power of 2 sized textures
bull It can be very slow
bull On some chipsets not all address modes work
42
Graphics
Writing Compatible Shaders
Query query
ndash Make sure to query for number of attributes varying and uniforms supported
bull Varies between devices
bull Not respecting will make your application crash
bull ldquoSupportedrdquo does not mean ldquoperforms wellrdquo
Conditions
ndash Avoid as much as possible
bull if necessary put them last in the shader
ndash Use mix() clamp() etc to create the same result
discard()
ndash Avoid discard()
bull if necessary it should be last
43
Graphics
Audio Solutions
Full track audio
s 45amp026
bull Plays multiple formats with codec support
bull Plays from filesystem or from network
bull Has high latency memory and CPU usage for quick sound effects
Sound effects and clips
s gtI984ampII0
bull Plays multiple formats with codec support
bull Preloads audio files to a pool
ndash Plays them with low latency
44
Sound
Audio Solutions
Application-generated audio
s $945I6T
bull Plays PCM audio only with minimal latency
bull Useful for applications that wish to perform sound processing or mixing
OpenSLES
ndash Combines capabilities of 45amp026 and $945I6T
ndash Available only in the NDK
ndash Requires Android 23 and higher
45
Sound
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
Use native AssetManager
ndash Gingerbread and Beyond
Targeting tricky trying tasks
Troubleshooting Tips and Tricks
47
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
One JNI Context Per Thread
Threading Options
49
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
JNI Context 2
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
OR
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
If all else fails Market filters
ndash Instruction set
ndash ARMv5ARMv7
ndash GL version
ndash Platform release
ndash Use Device Availability
Tips Standing Out from the Crowd
Start Small
ndash Download assets as-needed
ndash Hook me early instead of making me wait
Use Android backuprestore service (save to the cloud)
ndash Keep my progress when I switch devices
Support multiple control schemes
ndash Trackball D-pad virtual stick
ndash Let me decide what works best
Support install-to-SD
ndash Android Market users will knock your ratings if you donrsquot
51
Tips Standing Out from the Crowd
Profiling
ndash In-game profiling to select optimal settings per-device
Social
ndash Hook into social networks
ndash Use OpenID
Build a live wallpaper
ndash Own the userrsquos home screen with stats avatars
Analytics
ndash Market and in-game
In-app payments
ndash Consider alternative monetization techniques
52
Troubleshooting Development Tools
NVIDIA Debug Manager for Eclipse
ndash Simplifies setup for native debugger under Eclipse
bull developernvidiacomtegranvidia-debug-manager-android-ndk
WinGDB
ndash Use Visual Studio to debug Android NDK applications
bull wwwwingdbcom
vs-android
ndash Native MSBuild files for Android toolchain
bull vs-androidgooglecodecom
53
Troubleshooting Performance Tools
NVIDIA PerfHUD ES
ndash developernvidiacomtegraperfhud-es
Adreno Profiler
ndash developerqualcommcomshowcaseadreno-profiler
POWERVR Insider Utilities
ndash Including PVRTrace and PVRTune
ndash wwwimgteccompowervrinsiderpowervr-utilitiesasp
54
developerandroidcomsdkndkGoogleGameDevAndroid
Feedback httpgooglNudVs
QampA
55
8
Feature Library
C runtime libc
C++ runtime libstdc++
Math libm
Dynamic Linking libdl
Logging liblog
Zlib compression libz
OpenGL ES 11 libGLESv1_CM
OpenGL ES 20 libGLESv2
EGL libEGL
OpenSL ES libOpenSLES
Native framework NativeActivity) libandroid
JNI Graphics libjnigraphics
What the NDK is Not
Not the end of Dalvik
Not always higher performance
Not necessarily the right choice for every game
9
Dalvik vs C++
10
C++
Flexible
Easily Extensible
Android APIAccess
AutomaticMemory
Management
Fast
Low-Level
Common onOther Platforms
How to Use the NDK
11
Installing the NDK
Download NDK from developerandroidcomsdkndk
ndash Add NDK folder to your path
ndash Install Java JDK
ndash Install Ant
Windows
ndash Install Cygwin
bull Required for debugger
bull Recommended for build scripts
12
Development Flow
13
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Development Flow Project Setup
14
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Development Flow Project Setup
14
Created by $amp($))+$)(
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Project Setup
15
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Project Setup
15
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Created Manually
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Set up project
Write makefiles
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
$ampampampltPamp$(+)+-00+1234567QL6IER$ampampAgt++++++)+05BC0DE85$ampampampJ++++++++)+4B9C$ampamp$MJ++++++++++)+61B5+61B53NS
APP_STL = gnustl_static
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
$ampampampltPamp$(+)+-00+1234567QL6IER$ampampAgt++++++)+05BC0DE85$ampampampJ++++++++)+4B9C$ampamp$MJ++++++++++)+61B5+61B53NS
APP_STL = gnustl_static
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Interface Classes
Write interface in Java
ndash Use amp) keyword
17
LTC+I1K846I54KC0DE85U
QQ+H6LL6+VI6+8R5N+05B662
L9B05+0WW+GDPXJ5B+YR84W+$R5N5R2+Z
++WRR5+Z++++gt2WR1K0I45B662-[C0DE85[7U++
++Q]]+++]+^L61+_54R`+R`+9668R+N5_+_54R`+++]+^L61+`5C`R+R`+9668R+N5_+`5C`R+++]Q+++L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7U+++L9B05+WRR5+8R5N+NI54+WRL-7U
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
PXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]LPXJ8Na+EIBER+IBEa+E58R+a+E58R+B7+Z
++E0WW+0W++-]LPXJ8N73dGRBER0WW-LPXJ8Na+IBE7U
++E1R`I4J+54++-]LPXJ8N73dGRR`I4J-+++++++++++++++++++++++++++++LPXJ8Na+0Wa+[RTm2N8RW[a+[-n7=[7U
++-]LPXJ8N73d00=I54R`I4-LPXJ8Na+IBEa+54a+PXJltA7U
Development Flow Calling Dalvik Code Within CC++
20
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Build and Deploy
gt=0Alt-amp49BCDBEFG6HI
ndash Builds C libraries and emits so files
gt)-3
ndash (or ant release)
ndash Builds Java classes apk package
gtamp=44
ndash Deploys to emulator or device
21
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdbgdb-rsp over named pipe
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdb
EclipseVS
gdb-rsp over named pipe
gdb-MI
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Important Tip
B)-36amp3)$$)J23
Bringing Your Game to Android
24
Devices Accessing Android Market
25
Android 16
Android 15
Android 23
Android 233
Android 30
Two Week Period Published May 2011
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
NativeActivity is just starting
ndash 43 of checking-in devices can utilize it
ndash For non-tablet-specific titles we can take advantage of NativeActivity without becoming incompatible
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Platform-specific Resources
Using NativeActivity Compatibly
27
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dV0WcQBII0d++++cBII0+81[8IRG58C6B64[dR69cQBII0dcQ6WI96Wd
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dR69cQBII0d++++cBII0+81[8IRG58C6B64[dV0WcQBII0dcQ6WI96Wd
Using NativeActivity Compatibly
28
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
cR5N5R2+846I54)81[Kgt$XR5N$R5N5R2[+++846I54)8B04[^BII0QRWRG58C6B64[d++c1R34R+846I54)81[846I54KLLK05B81[+++++846I54)N09[W8R5N[+Qd++++++++++++++++++++++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6d++++++++++++cQR5N5R2dcR5N5R2+846I54)81[K1I$R5N5R2[+++846I54)8B04[^BII0Q8IRG58C6B64[d++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6dcQR5N5R2d
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+W8R5N$F$Ggt+)+3$XltJXm$gtltFJgt+ )+C09R50WK+k+ LL3846I5438R5NK$JMgt+)+30GgtND+3040+300IC+30G+30846I54$gt$JJMlt$ltJgt+ )+846I548R5NLLC09$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7-00+51LI6R31I490a846I54Q8R5NLLC097
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
LTC+I1KY1L0KW88C0WU
L9B05+0WW+gt$XR5N$R5N5R2+YR84W+846I54KLLKXR5N$R5N5R2+Z
++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
LTC+I1KY1L0KW88C0WU
L9B05+0WW+1I$R5N5R2+YR84W+846I54KLLK$R5N5R2+Z++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++++++gt2WR1K0I45B662-[WE85[7U++++KKK
Key Game Components
33
Lifecycle
Graphics Sound
Input
Assets
Activity LifecycleLifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Process LifecycleLifecycle
Android keeps application processes around for as long as possible
ndash Even when the activity is closed with V585W`-7 or the back key is pressed
The foreground activity process is considered the most important
ndash It can still be killed as a last resort
Visible activities are also given high priority
ndash Backgrounded activities are considered less important
ndash Processes with no active activities are killed first
Implications of the Process LifecycleLifecycle
Be careful with static initializers
ndash Your library cannot be unloaded while your process is active
bull Donrsquot assume that your static initializers will be run when your activity is created
Be careful with threads
ndash Threads are tied to the process not the activity
bull Your threads will continue to run at reduced priority even if your activity is backgrounded or destroyed
ndash Gameplay should stop during onPause
bull It might make sense to keep certain threads running - your activity may still be visible
ndash Make sure all native code is cleaned up during onDestroy
bull Users expect that your application will no longer be active when its activity is destroyed
The Basics
Key handling
ndash Your device most likely has capacitive buttons
bull Look for complete state transitions of I8m2I_8I8m2AL
bull Avoid overriding 45WLR`m2N8R
ndash Use I8m290R5L0I8m2I8Camp6WW
bull Keep your game behaving like an Android application
TouchMultitouch handling
ndash With I8I9`N8R
bull take advantage of built-in gesture processing
ndash use gt0GWR96RRI6 and GWR96RRI6
ndash Most devices now support multitouch
bull determine if your device can track distinct points
ndash `Wgt2WR1FR96-F$AltA(gtltXAJA(JgtJX)
37
Input
Other Input
Trackball handling
ndash With I86TB00N8R
bull Unhandled events turn into dpad events
Motion handling
ndash With I8gt8WI6`8C4
bull Must be registered with the gt8WI68C6
bull Disable unneeded sensors especially when paused
ndash Active sensors will quickly drain the battery
38
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
OpenGL
GLSurfaceView
ndash Creates the compatible context
bull Contexts are shared between native code and Dalvik
ndash Creates a rendering thread
ndash Releases the context during onPause
ndash Not the most efficient way to multitask withOpenGL but it avoids some driver issues
When context is lost
ndash Reload resources
bull Textures
bull Buffer objects
bull Shaders
ndash Names donrsquot persist
40
Graphics
Texture Formats
Android encourages innovation in hardware
ndash Chipset vendors use several kinds of proprietary texture compression formats
ndash OpenGL ES supports multiple compressed formats none mandatory
Solutions
ndash Uncompressed Textures
ndash Use ETC1 ndash broad support in 20
bull Optimized around photographic data
bull No Alpha
ndash Use Multi-APK (coming soon)
ndash Put textures on an asset server
bull Detect support at runtime
bull Download to each device
41
Graphics
Drawing for Performance
Draw order is important
ndash Has no impact on some platforms means everything on others
ndash Draw front to back to make best use of early rejects
Use VBOs
ndash Avoid unnecessary state changes
Textures
ndash Use power of 2 sized textures
bull It can be very slow
bull On some chipsets not all address modes work
42
Graphics
Writing Compatible Shaders
Query query
ndash Make sure to query for number of attributes varying and uniforms supported
bull Varies between devices
bull Not respecting will make your application crash
bull ldquoSupportedrdquo does not mean ldquoperforms wellrdquo
Conditions
ndash Avoid as much as possible
bull if necessary put them last in the shader
ndash Use mix() clamp() etc to create the same result
discard()
ndash Avoid discard()
bull if necessary it should be last
43
Graphics
Audio Solutions
Full track audio
s 45amp026
bull Plays multiple formats with codec support
bull Plays from filesystem or from network
bull Has high latency memory and CPU usage for quick sound effects
Sound effects and clips
s gtI984ampII0
bull Plays multiple formats with codec support
bull Preloads audio files to a pool
ndash Plays them with low latency
44
Sound
Audio Solutions
Application-generated audio
s $945I6T
bull Plays PCM audio only with minimal latency
bull Useful for applications that wish to perform sound processing or mixing
OpenSLES
ndash Combines capabilities of 45amp026 and $945I6T
ndash Available only in the NDK
ndash Requires Android 23 and higher
45
Sound
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
Use native AssetManager
ndash Gingerbread and Beyond
Targeting tricky trying tasks
Troubleshooting Tips and Tricks
47
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
One JNI Context Per Thread
Threading Options
49
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
JNI Context 2
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
OR
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
If all else fails Market filters
ndash Instruction set
ndash ARMv5ARMv7
ndash GL version
ndash Platform release
ndash Use Device Availability
Tips Standing Out from the Crowd
Start Small
ndash Download assets as-needed
ndash Hook me early instead of making me wait
Use Android backuprestore service (save to the cloud)
ndash Keep my progress when I switch devices
Support multiple control schemes
ndash Trackball D-pad virtual stick
ndash Let me decide what works best
Support install-to-SD
ndash Android Market users will knock your ratings if you donrsquot
51
Tips Standing Out from the Crowd
Profiling
ndash In-game profiling to select optimal settings per-device
Social
ndash Hook into social networks
ndash Use OpenID
Build a live wallpaper
ndash Own the userrsquos home screen with stats avatars
Analytics
ndash Market and in-game
In-app payments
ndash Consider alternative monetization techniques
52
Troubleshooting Development Tools
NVIDIA Debug Manager for Eclipse
ndash Simplifies setup for native debugger under Eclipse
bull developernvidiacomtegranvidia-debug-manager-android-ndk
WinGDB
ndash Use Visual Studio to debug Android NDK applications
bull wwwwingdbcom
vs-android
ndash Native MSBuild files for Android toolchain
bull vs-androidgooglecodecom
53
Troubleshooting Performance Tools
NVIDIA PerfHUD ES
ndash developernvidiacomtegraperfhud-es
Adreno Profiler
ndash developerqualcommcomshowcaseadreno-profiler
POWERVR Insider Utilities
ndash Including PVRTrace and PVRTune
ndash wwwimgteccompowervrinsiderpowervr-utilitiesasp
54
developerandroidcomsdkndkGoogleGameDevAndroid
Feedback httpgooglNudVs
QampA
55
What the NDK is Not
Not the end of Dalvik
Not always higher performance
Not necessarily the right choice for every game
9
Dalvik vs C++
10
C++
Flexible
Easily Extensible
Android APIAccess
AutomaticMemory
Management
Fast
Low-Level
Common onOther Platforms
How to Use the NDK
11
Installing the NDK
Download NDK from developerandroidcomsdkndk
ndash Add NDK folder to your path
ndash Install Java JDK
ndash Install Ant
Windows
ndash Install Cygwin
bull Required for debugger
bull Recommended for build scripts
12
Development Flow
13
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Development Flow Project Setup
14
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Development Flow Project Setup
14
Created by $amp($))+$)(
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Project Setup
15
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Project Setup
15
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Created Manually
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Set up project
Write makefiles
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
$ampampampltPamp$(+)+-00+1234567QL6IER$ampampAgt++++++)+05BC0DE85$ampampampJ++++++++)+4B9C$ampamp$MJ++++++++++)+61B5+61B53NS
APP_STL = gnustl_static
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
$ampampampltPamp$(+)+-00+1234567QL6IER$ampampAgt++++++)+05BC0DE85$ampampampJ++++++++)+4B9C$ampamp$MJ++++++++++)+61B5+61B53NS
APP_STL = gnustl_static
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Interface Classes
Write interface in Java
ndash Use amp) keyword
17
LTC+I1K846I54KC0DE85U
QQ+H6LL6+VI6+8R5N+05B662
L9B05+0WW+GDPXJ5B+YR84W+$R5N5R2+Z
++WRR5+Z++++gt2WR1K0I45B662-[C0DE85[7U++
++Q]]+++]+^L61+_54R`+R`+9668R+N5_+_54R`+++]+^L61+`5C`R+R`+9668R+N5_+`5C`R+++]Q+++L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7U+++L9B05+WRR5+8R5N+NI54+WRL-7U
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
PXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]LPXJ8Na+EIBER+IBEa+E58R+a+E58R+B7+Z
++E0WW+0W++-]LPXJ8N73dGRBER0WW-LPXJ8Na+IBE7U
++E1R`I4J+54++-]LPXJ8N73dGRR`I4J-+++++++++++++++++++++++++++++LPXJ8Na+0Wa+[RTm2N8RW[a+[-n7=[7U
++-]LPXJ8N73d00=I54R`I4-LPXJ8Na+IBEa+54a+PXJltA7U
Development Flow Calling Dalvik Code Within CC++
20
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Build and Deploy
gt=0Alt-amp49BCDBEFG6HI
ndash Builds C libraries and emits so files
gt)-3
ndash (or ant release)
ndash Builds Java classes apk package
gtamp=44
ndash Deploys to emulator or device
21
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdbgdb-rsp over named pipe
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdb
EclipseVS
gdb-rsp over named pipe
gdb-MI
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Important Tip
B)-36amp3)$$)J23
Bringing Your Game to Android
24
Devices Accessing Android Market
25
Android 16
Android 15
Android 23
Android 233
Android 30
Two Week Period Published May 2011
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
NativeActivity is just starting
ndash 43 of checking-in devices can utilize it
ndash For non-tablet-specific titles we can take advantage of NativeActivity without becoming incompatible
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Platform-specific Resources
Using NativeActivity Compatibly
27
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dV0WcQBII0d++++cBII0+81[8IRG58C6B64[dR69cQBII0dcQ6WI96Wd
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dR69cQBII0d++++cBII0+81[8IRG58C6B64[dV0WcQBII0dcQ6WI96Wd
Using NativeActivity Compatibly
28
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
cR5N5R2+846I54)81[Kgt$XR5N$R5N5R2[+++846I54)8B04[^BII0QRWRG58C6B64[d++c1R34R+846I54)81[846I54KLLK05B81[+++++846I54)N09[W8R5N[+Qd++++++++++++++++++++++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6d++++++++++++cQR5N5R2dcR5N5R2+846I54)81[K1I$R5N5R2[+++846I54)8B04[^BII0Q8IRG58C6B64[d++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6dcQR5N5R2d
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+W8R5N$F$Ggt+)+3$XltJXm$gtltFJgt+ )+C09R50WK+k+ LL3846I5438R5NK$JMgt+)+30GgtND+3040+300IC+30G+30846I54$gt$JJMlt$ltJgt+ )+846I548R5NLLC09$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7-00+51LI6R31I490a846I54Q8R5NLLC097
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
LTC+I1KY1L0KW88C0WU
L9B05+0WW+gt$XR5N$R5N5R2+YR84W+846I54KLLKXR5N$R5N5R2+Z
++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
LTC+I1KY1L0KW88C0WU
L9B05+0WW+1I$R5N5R2+YR84W+846I54KLLK$R5N5R2+Z++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++++++gt2WR1K0I45B662-[WE85[7U++++KKK
Key Game Components
33
Lifecycle
Graphics Sound
Input
Assets
Activity LifecycleLifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Process LifecycleLifecycle
Android keeps application processes around for as long as possible
ndash Even when the activity is closed with V585W`-7 or the back key is pressed
The foreground activity process is considered the most important
ndash It can still be killed as a last resort
Visible activities are also given high priority
ndash Backgrounded activities are considered less important
ndash Processes with no active activities are killed first
Implications of the Process LifecycleLifecycle
Be careful with static initializers
ndash Your library cannot be unloaded while your process is active
bull Donrsquot assume that your static initializers will be run when your activity is created
Be careful with threads
ndash Threads are tied to the process not the activity
bull Your threads will continue to run at reduced priority even if your activity is backgrounded or destroyed
ndash Gameplay should stop during onPause
bull It might make sense to keep certain threads running - your activity may still be visible
ndash Make sure all native code is cleaned up during onDestroy
bull Users expect that your application will no longer be active when its activity is destroyed
The Basics
Key handling
ndash Your device most likely has capacitive buttons
bull Look for complete state transitions of I8m2I_8I8m2AL
bull Avoid overriding 45WLR`m2N8R
ndash Use I8m290R5L0I8m2I8Camp6WW
bull Keep your game behaving like an Android application
TouchMultitouch handling
ndash With I8I9`N8R
bull take advantage of built-in gesture processing
ndash use gt0GWR96RRI6 and GWR96RRI6
ndash Most devices now support multitouch
bull determine if your device can track distinct points
ndash `Wgt2WR1FR96-F$AltA(gtltXAJA(JgtJX)
37
Input
Other Input
Trackball handling
ndash With I86TB00N8R
bull Unhandled events turn into dpad events
Motion handling
ndash With I8gt8WI6`8C4
bull Must be registered with the gt8WI68C6
bull Disable unneeded sensors especially when paused
ndash Active sensors will quickly drain the battery
38
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
OpenGL
GLSurfaceView
ndash Creates the compatible context
bull Contexts are shared between native code and Dalvik
ndash Creates a rendering thread
ndash Releases the context during onPause
ndash Not the most efficient way to multitask withOpenGL but it avoids some driver issues
When context is lost
ndash Reload resources
bull Textures
bull Buffer objects
bull Shaders
ndash Names donrsquot persist
40
Graphics
Texture Formats
Android encourages innovation in hardware
ndash Chipset vendors use several kinds of proprietary texture compression formats
ndash OpenGL ES supports multiple compressed formats none mandatory
Solutions
ndash Uncompressed Textures
ndash Use ETC1 ndash broad support in 20
bull Optimized around photographic data
bull No Alpha
ndash Use Multi-APK (coming soon)
ndash Put textures on an asset server
bull Detect support at runtime
bull Download to each device
41
Graphics
Drawing for Performance
Draw order is important
ndash Has no impact on some platforms means everything on others
ndash Draw front to back to make best use of early rejects
Use VBOs
ndash Avoid unnecessary state changes
Textures
ndash Use power of 2 sized textures
bull It can be very slow
bull On some chipsets not all address modes work
42
Graphics
Writing Compatible Shaders
Query query
ndash Make sure to query for number of attributes varying and uniforms supported
bull Varies between devices
bull Not respecting will make your application crash
bull ldquoSupportedrdquo does not mean ldquoperforms wellrdquo
Conditions
ndash Avoid as much as possible
bull if necessary put them last in the shader
ndash Use mix() clamp() etc to create the same result
discard()
ndash Avoid discard()
bull if necessary it should be last
43
Graphics
Audio Solutions
Full track audio
s 45amp026
bull Plays multiple formats with codec support
bull Plays from filesystem or from network
bull Has high latency memory and CPU usage for quick sound effects
Sound effects and clips
s gtI984ampII0
bull Plays multiple formats with codec support
bull Preloads audio files to a pool
ndash Plays them with low latency
44
Sound
Audio Solutions
Application-generated audio
s $945I6T
bull Plays PCM audio only with minimal latency
bull Useful for applications that wish to perform sound processing or mixing
OpenSLES
ndash Combines capabilities of 45amp026 and $945I6T
ndash Available only in the NDK
ndash Requires Android 23 and higher
45
Sound
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
Use native AssetManager
ndash Gingerbread and Beyond
Targeting tricky trying tasks
Troubleshooting Tips and Tricks
47
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
One JNI Context Per Thread
Threading Options
49
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
JNI Context 2
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
OR
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
If all else fails Market filters
ndash Instruction set
ndash ARMv5ARMv7
ndash GL version
ndash Platform release
ndash Use Device Availability
Tips Standing Out from the Crowd
Start Small
ndash Download assets as-needed
ndash Hook me early instead of making me wait
Use Android backuprestore service (save to the cloud)
ndash Keep my progress when I switch devices
Support multiple control schemes
ndash Trackball D-pad virtual stick
ndash Let me decide what works best
Support install-to-SD
ndash Android Market users will knock your ratings if you donrsquot
51
Tips Standing Out from the Crowd
Profiling
ndash In-game profiling to select optimal settings per-device
Social
ndash Hook into social networks
ndash Use OpenID
Build a live wallpaper
ndash Own the userrsquos home screen with stats avatars
Analytics
ndash Market and in-game
In-app payments
ndash Consider alternative monetization techniques
52
Troubleshooting Development Tools
NVIDIA Debug Manager for Eclipse
ndash Simplifies setup for native debugger under Eclipse
bull developernvidiacomtegranvidia-debug-manager-android-ndk
WinGDB
ndash Use Visual Studio to debug Android NDK applications
bull wwwwingdbcom
vs-android
ndash Native MSBuild files for Android toolchain
bull vs-androidgooglecodecom
53
Troubleshooting Performance Tools
NVIDIA PerfHUD ES
ndash developernvidiacomtegraperfhud-es
Adreno Profiler
ndash developerqualcommcomshowcaseadreno-profiler
POWERVR Insider Utilities
ndash Including PVRTrace and PVRTune
ndash wwwimgteccompowervrinsiderpowervr-utilitiesasp
54
developerandroidcomsdkndkGoogleGameDevAndroid
Feedback httpgooglNudVs
QampA
55
Dalvik vs C++
10
C++
Flexible
Easily Extensible
Android APIAccess
AutomaticMemory
Management
Fast
Low-Level
Common onOther Platforms
How to Use the NDK
11
Installing the NDK
Download NDK from developerandroidcomsdkndk
ndash Add NDK folder to your path
ndash Install Java JDK
ndash Install Ant
Windows
ndash Install Cygwin
bull Required for debugger
bull Recommended for build scripts
12
Development Flow
13
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Development Flow Project Setup
14
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Development Flow Project Setup
14
Created by $amp($))+$)(
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Project Setup
15
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Project Setup
15
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Created Manually
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Set up project
Write makefiles
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
$ampampampltPamp$(+)+-00+1234567QL6IER$ampampAgt++++++)+05BC0DE85$ampampampJ++++++++)+4B9C$ampamp$MJ++++++++++)+61B5+61B53NS
APP_STL = gnustl_static
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
$ampampampltPamp$(+)+-00+1234567QL6IER$ampampAgt++++++)+05BC0DE85$ampampampJ++++++++)+4B9C$ampamp$MJ++++++++++)+61B5+61B53NS
APP_STL = gnustl_static
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Interface Classes
Write interface in Java
ndash Use amp) keyword
17
LTC+I1K846I54KC0DE85U
QQ+H6LL6+VI6+8R5N+05B662
L9B05+0WW+GDPXJ5B+YR84W+$R5N5R2+Z
++WRR5+Z++++gt2WR1K0I45B662-[C0DE85[7U++
++Q]]+++]+^L61+_54R`+R`+9668R+N5_+_54R`+++]+^L61+`5C`R+R`+9668R+N5_+`5C`R+++]Q+++L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7U+++L9B05+WRR5+8R5N+NI54+WRL-7U
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
PXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]LPXJ8Na+EIBER+IBEa+E58R+a+E58R+B7+Z
++E0WW+0W++-]LPXJ8N73dGRBER0WW-LPXJ8Na+IBE7U
++E1R`I4J+54++-]LPXJ8N73dGRR`I4J-+++++++++++++++++++++++++++++LPXJ8Na+0Wa+[RTm2N8RW[a+[-n7=[7U
++-]LPXJ8N73d00=I54R`I4-LPXJ8Na+IBEa+54a+PXJltA7U
Development Flow Calling Dalvik Code Within CC++
20
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Build and Deploy
gt=0Alt-amp49BCDBEFG6HI
ndash Builds C libraries and emits so files
gt)-3
ndash (or ant release)
ndash Builds Java classes apk package
gtamp=44
ndash Deploys to emulator or device
21
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdbgdb-rsp over named pipe
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdb
EclipseVS
gdb-rsp over named pipe
gdb-MI
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Important Tip
B)-36amp3)$$)J23
Bringing Your Game to Android
24
Devices Accessing Android Market
25
Android 16
Android 15
Android 23
Android 233
Android 30
Two Week Period Published May 2011
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
NativeActivity is just starting
ndash 43 of checking-in devices can utilize it
ndash For non-tablet-specific titles we can take advantage of NativeActivity without becoming incompatible
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Platform-specific Resources
Using NativeActivity Compatibly
27
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dV0WcQBII0d++++cBII0+81[8IRG58C6B64[dR69cQBII0dcQ6WI96Wd
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dR69cQBII0d++++cBII0+81[8IRG58C6B64[dV0WcQBII0dcQ6WI96Wd
Using NativeActivity Compatibly
28
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
cR5N5R2+846I54)81[Kgt$XR5N$R5N5R2[+++846I54)8B04[^BII0QRWRG58C6B64[d++c1R34R+846I54)81[846I54KLLK05B81[+++++846I54)N09[W8R5N[+Qd++++++++++++++++++++++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6d++++++++++++cQR5N5R2dcR5N5R2+846I54)81[K1I$R5N5R2[+++846I54)8B04[^BII0Q8IRG58C6B64[d++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6dcQR5N5R2d
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+W8R5N$F$Ggt+)+3$XltJXm$gtltFJgt+ )+C09R50WK+k+ LL3846I5438R5NK$JMgt+)+30GgtND+3040+300IC+30G+30846I54$gt$JJMlt$ltJgt+ )+846I548R5NLLC09$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7-00+51LI6R31I490a846I54Q8R5NLLC097
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
LTC+I1KY1L0KW88C0WU
L9B05+0WW+gt$XR5N$R5N5R2+YR84W+846I54KLLKXR5N$R5N5R2+Z
++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
LTC+I1KY1L0KW88C0WU
L9B05+0WW+1I$R5N5R2+YR84W+846I54KLLK$R5N5R2+Z++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++++++gt2WR1K0I45B662-[WE85[7U++++KKK
Key Game Components
33
Lifecycle
Graphics Sound
Input
Assets
Activity LifecycleLifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Process LifecycleLifecycle
Android keeps application processes around for as long as possible
ndash Even when the activity is closed with V585W`-7 or the back key is pressed
The foreground activity process is considered the most important
ndash It can still be killed as a last resort
Visible activities are also given high priority
ndash Backgrounded activities are considered less important
ndash Processes with no active activities are killed first
Implications of the Process LifecycleLifecycle
Be careful with static initializers
ndash Your library cannot be unloaded while your process is active
bull Donrsquot assume that your static initializers will be run when your activity is created
Be careful with threads
ndash Threads are tied to the process not the activity
bull Your threads will continue to run at reduced priority even if your activity is backgrounded or destroyed
ndash Gameplay should stop during onPause
bull It might make sense to keep certain threads running - your activity may still be visible
ndash Make sure all native code is cleaned up during onDestroy
bull Users expect that your application will no longer be active when its activity is destroyed
The Basics
Key handling
ndash Your device most likely has capacitive buttons
bull Look for complete state transitions of I8m2I_8I8m2AL
bull Avoid overriding 45WLR`m2N8R
ndash Use I8m290R5L0I8m2I8Camp6WW
bull Keep your game behaving like an Android application
TouchMultitouch handling
ndash With I8I9`N8R
bull take advantage of built-in gesture processing
ndash use gt0GWR96RRI6 and GWR96RRI6
ndash Most devices now support multitouch
bull determine if your device can track distinct points
ndash `Wgt2WR1FR96-F$AltA(gtltXAJA(JgtJX)
37
Input
Other Input
Trackball handling
ndash With I86TB00N8R
bull Unhandled events turn into dpad events
Motion handling
ndash With I8gt8WI6`8C4
bull Must be registered with the gt8WI68C6
bull Disable unneeded sensors especially when paused
ndash Active sensors will quickly drain the battery
38
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
OpenGL
GLSurfaceView
ndash Creates the compatible context
bull Contexts are shared between native code and Dalvik
ndash Creates a rendering thread
ndash Releases the context during onPause
ndash Not the most efficient way to multitask withOpenGL but it avoids some driver issues
When context is lost
ndash Reload resources
bull Textures
bull Buffer objects
bull Shaders
ndash Names donrsquot persist
40
Graphics
Texture Formats
Android encourages innovation in hardware
ndash Chipset vendors use several kinds of proprietary texture compression formats
ndash OpenGL ES supports multiple compressed formats none mandatory
Solutions
ndash Uncompressed Textures
ndash Use ETC1 ndash broad support in 20
bull Optimized around photographic data
bull No Alpha
ndash Use Multi-APK (coming soon)
ndash Put textures on an asset server
bull Detect support at runtime
bull Download to each device
41
Graphics
Drawing for Performance
Draw order is important
ndash Has no impact on some platforms means everything on others
ndash Draw front to back to make best use of early rejects
Use VBOs
ndash Avoid unnecessary state changes
Textures
ndash Use power of 2 sized textures
bull It can be very slow
bull On some chipsets not all address modes work
42
Graphics
Writing Compatible Shaders
Query query
ndash Make sure to query for number of attributes varying and uniforms supported
bull Varies between devices
bull Not respecting will make your application crash
bull ldquoSupportedrdquo does not mean ldquoperforms wellrdquo
Conditions
ndash Avoid as much as possible
bull if necessary put them last in the shader
ndash Use mix() clamp() etc to create the same result
discard()
ndash Avoid discard()
bull if necessary it should be last
43
Graphics
Audio Solutions
Full track audio
s 45amp026
bull Plays multiple formats with codec support
bull Plays from filesystem or from network
bull Has high latency memory and CPU usage for quick sound effects
Sound effects and clips
s gtI984ampII0
bull Plays multiple formats with codec support
bull Preloads audio files to a pool
ndash Plays them with low latency
44
Sound
Audio Solutions
Application-generated audio
s $945I6T
bull Plays PCM audio only with minimal latency
bull Useful for applications that wish to perform sound processing or mixing
OpenSLES
ndash Combines capabilities of 45amp026 and $945I6T
ndash Available only in the NDK
ndash Requires Android 23 and higher
45
Sound
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
Use native AssetManager
ndash Gingerbread and Beyond
Targeting tricky trying tasks
Troubleshooting Tips and Tricks
47
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
One JNI Context Per Thread
Threading Options
49
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
JNI Context 2
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
OR
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
If all else fails Market filters
ndash Instruction set
ndash ARMv5ARMv7
ndash GL version
ndash Platform release
ndash Use Device Availability
Tips Standing Out from the Crowd
Start Small
ndash Download assets as-needed
ndash Hook me early instead of making me wait
Use Android backuprestore service (save to the cloud)
ndash Keep my progress when I switch devices
Support multiple control schemes
ndash Trackball D-pad virtual stick
ndash Let me decide what works best
Support install-to-SD
ndash Android Market users will knock your ratings if you donrsquot
51
Tips Standing Out from the Crowd
Profiling
ndash In-game profiling to select optimal settings per-device
Social
ndash Hook into social networks
ndash Use OpenID
Build a live wallpaper
ndash Own the userrsquos home screen with stats avatars
Analytics
ndash Market and in-game
In-app payments
ndash Consider alternative monetization techniques
52
Troubleshooting Development Tools
NVIDIA Debug Manager for Eclipse
ndash Simplifies setup for native debugger under Eclipse
bull developernvidiacomtegranvidia-debug-manager-android-ndk
WinGDB
ndash Use Visual Studio to debug Android NDK applications
bull wwwwingdbcom
vs-android
ndash Native MSBuild files for Android toolchain
bull vs-androidgooglecodecom
53
Troubleshooting Performance Tools
NVIDIA PerfHUD ES
ndash developernvidiacomtegraperfhud-es
Adreno Profiler
ndash developerqualcommcomshowcaseadreno-profiler
POWERVR Insider Utilities
ndash Including PVRTrace and PVRTune
ndash wwwimgteccompowervrinsiderpowervr-utilitiesasp
54
developerandroidcomsdkndkGoogleGameDevAndroid
Feedback httpgooglNudVs
QampA
55
How to Use the NDK
11
Installing the NDK
Download NDK from developerandroidcomsdkndk
ndash Add NDK folder to your path
ndash Install Java JDK
ndash Install Ant
Windows
ndash Install Cygwin
bull Required for debugger
bull Recommended for build scripts
12
Development Flow
13
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Development Flow Project Setup
14
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Development Flow Project Setup
14
Created by $amp($))+$)(
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Project Setup
15
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Project Setup
15
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Created Manually
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Set up project
Write makefiles
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
$ampampampltPamp$(+)+-00+1234567QL6IER$ampampAgt++++++)+05BC0DE85$ampampampJ++++++++)+4B9C$ampamp$MJ++++++++++)+61B5+61B53NS
APP_STL = gnustl_static
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
$ampampampltPamp$(+)+-00+1234567QL6IER$ampampAgt++++++)+05BC0DE85$ampampampJ++++++++)+4B9C$ampamp$MJ++++++++++)+61B5+61B53NS
APP_STL = gnustl_static
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Interface Classes
Write interface in Java
ndash Use amp) keyword
17
LTC+I1K846I54KC0DE85U
QQ+H6LL6+VI6+8R5N+05B662
L9B05+0WW+GDPXJ5B+YR84W+$R5N5R2+Z
++WRR5+Z++++gt2WR1K0I45B662-[C0DE85[7U++
++Q]]+++]+^L61+_54R`+R`+9668R+N5_+_54R`+++]+^L61+`5C`R+R`+9668R+N5_+`5C`R+++]Q+++L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7U+++L9B05+WRR5+8R5N+NI54+WRL-7U
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
PXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]LPXJ8Na+EIBER+IBEa+E58R+a+E58R+B7+Z
++E0WW+0W++-]LPXJ8N73dGRBER0WW-LPXJ8Na+IBE7U
++E1R`I4J+54++-]LPXJ8N73dGRR`I4J-+++++++++++++++++++++++++++++LPXJ8Na+0Wa+[RTm2N8RW[a+[-n7=[7U
++-]LPXJ8N73d00=I54R`I4-LPXJ8Na+IBEa+54a+PXJltA7U
Development Flow Calling Dalvik Code Within CC++
20
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Build and Deploy
gt=0Alt-amp49BCDBEFG6HI
ndash Builds C libraries and emits so files
gt)-3
ndash (or ant release)
ndash Builds Java classes apk package
gtamp=44
ndash Deploys to emulator or device
21
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdbgdb-rsp over named pipe
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdb
EclipseVS
gdb-rsp over named pipe
gdb-MI
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Important Tip
B)-36amp3)$$)J23
Bringing Your Game to Android
24
Devices Accessing Android Market
25
Android 16
Android 15
Android 23
Android 233
Android 30
Two Week Period Published May 2011
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
NativeActivity is just starting
ndash 43 of checking-in devices can utilize it
ndash For non-tablet-specific titles we can take advantage of NativeActivity without becoming incompatible
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Platform-specific Resources
Using NativeActivity Compatibly
27
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dV0WcQBII0d++++cBII0+81[8IRG58C6B64[dR69cQBII0dcQ6WI96Wd
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dR69cQBII0d++++cBII0+81[8IRG58C6B64[dV0WcQBII0dcQ6WI96Wd
Using NativeActivity Compatibly
28
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
cR5N5R2+846I54)81[Kgt$XR5N$R5N5R2[+++846I54)8B04[^BII0QRWRG58C6B64[d++c1R34R+846I54)81[846I54KLLK05B81[+++++846I54)N09[W8R5N[+Qd++++++++++++++++++++++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6d++++++++++++cQR5N5R2dcR5N5R2+846I54)81[K1I$R5N5R2[+++846I54)8B04[^BII0Q8IRG58C6B64[d++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6dcQR5N5R2d
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+W8R5N$F$Ggt+)+3$XltJXm$gtltFJgt+ )+C09R50WK+k+ LL3846I5438R5NK$JMgt+)+30GgtND+3040+300IC+30G+30846I54$gt$JJMlt$ltJgt+ )+846I548R5NLLC09$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7-00+51LI6R31I490a846I54Q8R5NLLC097
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
LTC+I1KY1L0KW88C0WU
L9B05+0WW+gt$XR5N$R5N5R2+YR84W+846I54KLLKXR5N$R5N5R2+Z
++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
LTC+I1KY1L0KW88C0WU
L9B05+0WW+1I$R5N5R2+YR84W+846I54KLLK$R5N5R2+Z++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++++++gt2WR1K0I45B662-[WE85[7U++++KKK
Key Game Components
33
Lifecycle
Graphics Sound
Input
Assets
Activity LifecycleLifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Process LifecycleLifecycle
Android keeps application processes around for as long as possible
ndash Even when the activity is closed with V585W`-7 or the back key is pressed
The foreground activity process is considered the most important
ndash It can still be killed as a last resort
Visible activities are also given high priority
ndash Backgrounded activities are considered less important
ndash Processes with no active activities are killed first
Implications of the Process LifecycleLifecycle
Be careful with static initializers
ndash Your library cannot be unloaded while your process is active
bull Donrsquot assume that your static initializers will be run when your activity is created
Be careful with threads
ndash Threads are tied to the process not the activity
bull Your threads will continue to run at reduced priority even if your activity is backgrounded or destroyed
ndash Gameplay should stop during onPause
bull It might make sense to keep certain threads running - your activity may still be visible
ndash Make sure all native code is cleaned up during onDestroy
bull Users expect that your application will no longer be active when its activity is destroyed
The Basics
Key handling
ndash Your device most likely has capacitive buttons
bull Look for complete state transitions of I8m2I_8I8m2AL
bull Avoid overriding 45WLR`m2N8R
ndash Use I8m290R5L0I8m2I8Camp6WW
bull Keep your game behaving like an Android application
TouchMultitouch handling
ndash With I8I9`N8R
bull take advantage of built-in gesture processing
ndash use gt0GWR96RRI6 and GWR96RRI6
ndash Most devices now support multitouch
bull determine if your device can track distinct points
ndash `Wgt2WR1FR96-F$AltA(gtltXAJA(JgtJX)
37
Input
Other Input
Trackball handling
ndash With I86TB00N8R
bull Unhandled events turn into dpad events
Motion handling
ndash With I8gt8WI6`8C4
bull Must be registered with the gt8WI68C6
bull Disable unneeded sensors especially when paused
ndash Active sensors will quickly drain the battery
38
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
OpenGL
GLSurfaceView
ndash Creates the compatible context
bull Contexts are shared between native code and Dalvik
ndash Creates a rendering thread
ndash Releases the context during onPause
ndash Not the most efficient way to multitask withOpenGL but it avoids some driver issues
When context is lost
ndash Reload resources
bull Textures
bull Buffer objects
bull Shaders
ndash Names donrsquot persist
40
Graphics
Texture Formats
Android encourages innovation in hardware
ndash Chipset vendors use several kinds of proprietary texture compression formats
ndash OpenGL ES supports multiple compressed formats none mandatory
Solutions
ndash Uncompressed Textures
ndash Use ETC1 ndash broad support in 20
bull Optimized around photographic data
bull No Alpha
ndash Use Multi-APK (coming soon)
ndash Put textures on an asset server
bull Detect support at runtime
bull Download to each device
41
Graphics
Drawing for Performance
Draw order is important
ndash Has no impact on some platforms means everything on others
ndash Draw front to back to make best use of early rejects
Use VBOs
ndash Avoid unnecessary state changes
Textures
ndash Use power of 2 sized textures
bull It can be very slow
bull On some chipsets not all address modes work
42
Graphics
Writing Compatible Shaders
Query query
ndash Make sure to query for number of attributes varying and uniforms supported
bull Varies between devices
bull Not respecting will make your application crash
bull ldquoSupportedrdquo does not mean ldquoperforms wellrdquo
Conditions
ndash Avoid as much as possible
bull if necessary put them last in the shader
ndash Use mix() clamp() etc to create the same result
discard()
ndash Avoid discard()
bull if necessary it should be last
43
Graphics
Audio Solutions
Full track audio
s 45amp026
bull Plays multiple formats with codec support
bull Plays from filesystem or from network
bull Has high latency memory and CPU usage for quick sound effects
Sound effects and clips
s gtI984ampII0
bull Plays multiple formats with codec support
bull Preloads audio files to a pool
ndash Plays them with low latency
44
Sound
Audio Solutions
Application-generated audio
s $945I6T
bull Plays PCM audio only with minimal latency
bull Useful for applications that wish to perform sound processing or mixing
OpenSLES
ndash Combines capabilities of 45amp026 and $945I6T
ndash Available only in the NDK
ndash Requires Android 23 and higher
45
Sound
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
Use native AssetManager
ndash Gingerbread and Beyond
Targeting tricky trying tasks
Troubleshooting Tips and Tricks
47
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
One JNI Context Per Thread
Threading Options
49
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
JNI Context 2
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
OR
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
If all else fails Market filters
ndash Instruction set
ndash ARMv5ARMv7
ndash GL version
ndash Platform release
ndash Use Device Availability
Tips Standing Out from the Crowd
Start Small
ndash Download assets as-needed
ndash Hook me early instead of making me wait
Use Android backuprestore service (save to the cloud)
ndash Keep my progress when I switch devices
Support multiple control schemes
ndash Trackball D-pad virtual stick
ndash Let me decide what works best
Support install-to-SD
ndash Android Market users will knock your ratings if you donrsquot
51
Tips Standing Out from the Crowd
Profiling
ndash In-game profiling to select optimal settings per-device
Social
ndash Hook into social networks
ndash Use OpenID
Build a live wallpaper
ndash Own the userrsquos home screen with stats avatars
Analytics
ndash Market and in-game
In-app payments
ndash Consider alternative monetization techniques
52
Troubleshooting Development Tools
NVIDIA Debug Manager for Eclipse
ndash Simplifies setup for native debugger under Eclipse
bull developernvidiacomtegranvidia-debug-manager-android-ndk
WinGDB
ndash Use Visual Studio to debug Android NDK applications
bull wwwwingdbcom
vs-android
ndash Native MSBuild files for Android toolchain
bull vs-androidgooglecodecom
53
Troubleshooting Performance Tools
NVIDIA PerfHUD ES
ndash developernvidiacomtegraperfhud-es
Adreno Profiler
ndash developerqualcommcomshowcaseadreno-profiler
POWERVR Insider Utilities
ndash Including PVRTrace and PVRTune
ndash wwwimgteccompowervrinsiderpowervr-utilitiesasp
54
developerandroidcomsdkndkGoogleGameDevAndroid
Feedback httpgooglNudVs
QampA
55
Installing the NDK
Download NDK from developerandroidcomsdkndk
ndash Add NDK folder to your path
ndash Install Java JDK
ndash Install Ant
Windows
ndash Install Cygwin
bull Required for debugger
bull Recommended for build scripts
12
Development Flow
13
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Development Flow Project Setup
14
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Development Flow Project Setup
14
Created by $amp($))+$)(
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Project Setup
15
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Project Setup
15
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Created Manually
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Set up project
Write makefiles
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
$ampampampltPamp$(+)+-00+1234567QL6IER$ampampAgt++++++)+05BC0DE85$ampampampJ++++++++)+4B9C$ampamp$MJ++++++++++)+61B5+61B53NS
APP_STL = gnustl_static
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
$ampampampltPamp$(+)+-00+1234567QL6IER$ampampAgt++++++)+05BC0DE85$ampampampJ++++++++)+4B9C$ampamp$MJ++++++++++)+61B5+61B53NS
APP_STL = gnustl_static
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Interface Classes
Write interface in Java
ndash Use amp) keyword
17
LTC+I1K846I54KC0DE85U
QQ+H6LL6+VI6+8R5N+05B662
L9B05+0WW+GDPXJ5B+YR84W+$R5N5R2+Z
++WRR5+Z++++gt2WR1K0I45B662-[C0DE85[7U++
++Q]]+++]+^L61+_54R`+R`+9668R+N5_+_54R`+++]+^L61+`5C`R+R`+9668R+N5_+`5C`R+++]Q+++L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7U+++L9B05+WRR5+8R5N+NI54+WRL-7U
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
PXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]LPXJ8Na+EIBER+IBEa+E58R+a+E58R+B7+Z
++E0WW+0W++-]LPXJ8N73dGRBER0WW-LPXJ8Na+IBE7U
++E1R`I4J+54++-]LPXJ8N73dGRR`I4J-+++++++++++++++++++++++++++++LPXJ8Na+0Wa+[RTm2N8RW[a+[-n7=[7U
++-]LPXJ8N73d00=I54R`I4-LPXJ8Na+IBEa+54a+PXJltA7U
Development Flow Calling Dalvik Code Within CC++
20
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Build and Deploy
gt=0Alt-amp49BCDBEFG6HI
ndash Builds C libraries and emits so files
gt)-3
ndash (or ant release)
ndash Builds Java classes apk package
gtamp=44
ndash Deploys to emulator or device
21
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdbgdb-rsp over named pipe
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdb
EclipseVS
gdb-rsp over named pipe
gdb-MI
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Important Tip
B)-36amp3)$$)J23
Bringing Your Game to Android
24
Devices Accessing Android Market
25
Android 16
Android 15
Android 23
Android 233
Android 30
Two Week Period Published May 2011
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
NativeActivity is just starting
ndash 43 of checking-in devices can utilize it
ndash For non-tablet-specific titles we can take advantage of NativeActivity without becoming incompatible
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Platform-specific Resources
Using NativeActivity Compatibly
27
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dV0WcQBII0d++++cBII0+81[8IRG58C6B64[dR69cQBII0dcQ6WI96Wd
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dR69cQBII0d++++cBII0+81[8IRG58C6B64[dV0WcQBII0dcQ6WI96Wd
Using NativeActivity Compatibly
28
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
cR5N5R2+846I54)81[Kgt$XR5N$R5N5R2[+++846I54)8B04[^BII0QRWRG58C6B64[d++c1R34R+846I54)81[846I54KLLK05B81[+++++846I54)N09[W8R5N[+Qd++++++++++++++++++++++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6d++++++++++++cQR5N5R2dcR5N5R2+846I54)81[K1I$R5N5R2[+++846I54)8B04[^BII0Q8IRG58C6B64[d++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6dcQR5N5R2d
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+W8R5N$F$Ggt+)+3$XltJXm$gtltFJgt+ )+C09R50WK+k+ LL3846I5438R5NK$JMgt+)+30GgtND+3040+300IC+30G+30846I54$gt$JJMlt$ltJgt+ )+846I548R5NLLC09$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7-00+51LI6R31I490a846I54Q8R5NLLC097
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
LTC+I1KY1L0KW88C0WU
L9B05+0WW+gt$XR5N$R5N5R2+YR84W+846I54KLLKXR5N$R5N5R2+Z
++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
LTC+I1KY1L0KW88C0WU
L9B05+0WW+1I$R5N5R2+YR84W+846I54KLLK$R5N5R2+Z++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++++++gt2WR1K0I45B662-[WE85[7U++++KKK
Key Game Components
33
Lifecycle
Graphics Sound
Input
Assets
Activity LifecycleLifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Process LifecycleLifecycle
Android keeps application processes around for as long as possible
ndash Even when the activity is closed with V585W`-7 or the back key is pressed
The foreground activity process is considered the most important
ndash It can still be killed as a last resort
Visible activities are also given high priority
ndash Backgrounded activities are considered less important
ndash Processes with no active activities are killed first
Implications of the Process LifecycleLifecycle
Be careful with static initializers
ndash Your library cannot be unloaded while your process is active
bull Donrsquot assume that your static initializers will be run when your activity is created
Be careful with threads
ndash Threads are tied to the process not the activity
bull Your threads will continue to run at reduced priority even if your activity is backgrounded or destroyed
ndash Gameplay should stop during onPause
bull It might make sense to keep certain threads running - your activity may still be visible
ndash Make sure all native code is cleaned up during onDestroy
bull Users expect that your application will no longer be active when its activity is destroyed
The Basics
Key handling
ndash Your device most likely has capacitive buttons
bull Look for complete state transitions of I8m2I_8I8m2AL
bull Avoid overriding 45WLR`m2N8R
ndash Use I8m290R5L0I8m2I8Camp6WW
bull Keep your game behaving like an Android application
TouchMultitouch handling
ndash With I8I9`N8R
bull take advantage of built-in gesture processing
ndash use gt0GWR96RRI6 and GWR96RRI6
ndash Most devices now support multitouch
bull determine if your device can track distinct points
ndash `Wgt2WR1FR96-F$AltA(gtltXAJA(JgtJX)
37
Input
Other Input
Trackball handling
ndash With I86TB00N8R
bull Unhandled events turn into dpad events
Motion handling
ndash With I8gt8WI6`8C4
bull Must be registered with the gt8WI68C6
bull Disable unneeded sensors especially when paused
ndash Active sensors will quickly drain the battery
38
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
OpenGL
GLSurfaceView
ndash Creates the compatible context
bull Contexts are shared between native code and Dalvik
ndash Creates a rendering thread
ndash Releases the context during onPause
ndash Not the most efficient way to multitask withOpenGL but it avoids some driver issues
When context is lost
ndash Reload resources
bull Textures
bull Buffer objects
bull Shaders
ndash Names donrsquot persist
40
Graphics
Texture Formats
Android encourages innovation in hardware
ndash Chipset vendors use several kinds of proprietary texture compression formats
ndash OpenGL ES supports multiple compressed formats none mandatory
Solutions
ndash Uncompressed Textures
ndash Use ETC1 ndash broad support in 20
bull Optimized around photographic data
bull No Alpha
ndash Use Multi-APK (coming soon)
ndash Put textures on an asset server
bull Detect support at runtime
bull Download to each device
41
Graphics
Drawing for Performance
Draw order is important
ndash Has no impact on some platforms means everything on others
ndash Draw front to back to make best use of early rejects
Use VBOs
ndash Avoid unnecessary state changes
Textures
ndash Use power of 2 sized textures
bull It can be very slow
bull On some chipsets not all address modes work
42
Graphics
Writing Compatible Shaders
Query query
ndash Make sure to query for number of attributes varying and uniforms supported
bull Varies between devices
bull Not respecting will make your application crash
bull ldquoSupportedrdquo does not mean ldquoperforms wellrdquo
Conditions
ndash Avoid as much as possible
bull if necessary put them last in the shader
ndash Use mix() clamp() etc to create the same result
discard()
ndash Avoid discard()
bull if necessary it should be last
43
Graphics
Audio Solutions
Full track audio
s 45amp026
bull Plays multiple formats with codec support
bull Plays from filesystem or from network
bull Has high latency memory and CPU usage for quick sound effects
Sound effects and clips
s gtI984ampII0
bull Plays multiple formats with codec support
bull Preloads audio files to a pool
ndash Plays them with low latency
44
Sound
Audio Solutions
Application-generated audio
s $945I6T
bull Plays PCM audio only with minimal latency
bull Useful for applications that wish to perform sound processing or mixing
OpenSLES
ndash Combines capabilities of 45amp026 and $945I6T
ndash Available only in the NDK
ndash Requires Android 23 and higher
45
Sound
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
Use native AssetManager
ndash Gingerbread and Beyond
Targeting tricky trying tasks
Troubleshooting Tips and Tricks
47
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
One JNI Context Per Thread
Threading Options
49
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
JNI Context 2
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
OR
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
If all else fails Market filters
ndash Instruction set
ndash ARMv5ARMv7
ndash GL version
ndash Platform release
ndash Use Device Availability
Tips Standing Out from the Crowd
Start Small
ndash Download assets as-needed
ndash Hook me early instead of making me wait
Use Android backuprestore service (save to the cloud)
ndash Keep my progress when I switch devices
Support multiple control schemes
ndash Trackball D-pad virtual stick
ndash Let me decide what works best
Support install-to-SD
ndash Android Market users will knock your ratings if you donrsquot
51
Tips Standing Out from the Crowd
Profiling
ndash In-game profiling to select optimal settings per-device
Social
ndash Hook into social networks
ndash Use OpenID
Build a live wallpaper
ndash Own the userrsquos home screen with stats avatars
Analytics
ndash Market and in-game
In-app payments
ndash Consider alternative monetization techniques
52
Troubleshooting Development Tools
NVIDIA Debug Manager for Eclipse
ndash Simplifies setup for native debugger under Eclipse
bull developernvidiacomtegranvidia-debug-manager-android-ndk
WinGDB
ndash Use Visual Studio to debug Android NDK applications
bull wwwwingdbcom
vs-android
ndash Native MSBuild files for Android toolchain
bull vs-androidgooglecodecom
53
Troubleshooting Performance Tools
NVIDIA PerfHUD ES
ndash developernvidiacomtegraperfhud-es
Adreno Profiler
ndash developerqualcommcomshowcaseadreno-profiler
POWERVR Insider Utilities
ndash Including PVRTrace and PVRTune
ndash wwwimgteccompowervrinsiderpowervr-utilitiesasp
54
developerandroidcomsdkndkGoogleGameDevAndroid
Feedback httpgooglNudVs
QampA
55
Development Flow
13
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Development Flow Project Setup
14
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Development Flow Project Setup
14
Created by $amp($))+$)(
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Project Setup
15
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Project Setup
15
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Created Manually
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Set up project
Write makefiles
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
$ampampampltPamp$(+)+-00+1234567QL6IER$ampampAgt++++++)+05BC0DE85$ampampampJ++++++++)+4B9C$ampamp$MJ++++++++++)+61B5+61B53NS
APP_STL = gnustl_static
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
$ampampampltPamp$(+)+-00+1234567QL6IER$ampampAgt++++++)+05BC0DE85$ampampampJ++++++++)+4B9C$ampamp$MJ++++++++++)+61B5+61B53NS
APP_STL = gnustl_static
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Interface Classes
Write interface in Java
ndash Use amp) keyword
17
LTC+I1K846I54KC0DE85U
QQ+H6LL6+VI6+8R5N+05B662
L9B05+0WW+GDPXJ5B+YR84W+$R5N5R2+Z
++WRR5+Z++++gt2WR1K0I45B662-[C0DE85[7U++
++Q]]+++]+^L61+_54R`+R`+9668R+N5_+_54R`+++]+^L61+`5C`R+R`+9668R+N5_+`5C`R+++]Q+++L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7U+++L9B05+WRR5+8R5N+NI54+WRL-7U
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
PXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]LPXJ8Na+EIBER+IBEa+E58R+a+E58R+B7+Z
++E0WW+0W++-]LPXJ8N73dGRBER0WW-LPXJ8Na+IBE7U
++E1R`I4J+54++-]LPXJ8N73dGRR`I4J-+++++++++++++++++++++++++++++LPXJ8Na+0Wa+[RTm2N8RW[a+[-n7=[7U
++-]LPXJ8N73d00=I54R`I4-LPXJ8Na+IBEa+54a+PXJltA7U
Development Flow Calling Dalvik Code Within CC++
20
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Build and Deploy
gt=0Alt-amp49BCDBEFG6HI
ndash Builds C libraries and emits so files
gt)-3
ndash (or ant release)
ndash Builds Java classes apk package
gtamp=44
ndash Deploys to emulator or device
21
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdbgdb-rsp over named pipe
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdb
EclipseVS
gdb-rsp over named pipe
gdb-MI
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Important Tip
B)-36amp3)$$)J23
Bringing Your Game to Android
24
Devices Accessing Android Market
25
Android 16
Android 15
Android 23
Android 233
Android 30
Two Week Period Published May 2011
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
NativeActivity is just starting
ndash 43 of checking-in devices can utilize it
ndash For non-tablet-specific titles we can take advantage of NativeActivity without becoming incompatible
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Platform-specific Resources
Using NativeActivity Compatibly
27
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dV0WcQBII0d++++cBII0+81[8IRG58C6B64[dR69cQBII0dcQ6WI96Wd
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dR69cQBII0d++++cBII0+81[8IRG58C6B64[dV0WcQBII0dcQ6WI96Wd
Using NativeActivity Compatibly
28
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
cR5N5R2+846I54)81[Kgt$XR5N$R5N5R2[+++846I54)8B04[^BII0QRWRG58C6B64[d++c1R34R+846I54)81[846I54KLLK05B81[+++++846I54)N09[W8R5N[+Qd++++++++++++++++++++++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6d++++++++++++cQR5N5R2dcR5N5R2+846I54)81[K1I$R5N5R2[+++846I54)8B04[^BII0Q8IRG58C6B64[d++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6dcQR5N5R2d
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+W8R5N$F$Ggt+)+3$XltJXm$gtltFJgt+ )+C09R50WK+k+ LL3846I5438R5NK$JMgt+)+30GgtND+3040+300IC+30G+30846I54$gt$JJMlt$ltJgt+ )+846I548R5NLLC09$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7-00+51LI6R31I490a846I54Q8R5NLLC097
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
LTC+I1KY1L0KW88C0WU
L9B05+0WW+gt$XR5N$R5N5R2+YR84W+846I54KLLKXR5N$R5N5R2+Z
++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
LTC+I1KY1L0KW88C0WU
L9B05+0WW+1I$R5N5R2+YR84W+846I54KLLK$R5N5R2+Z++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++++++gt2WR1K0I45B662-[WE85[7U++++KKK
Key Game Components
33
Lifecycle
Graphics Sound
Input
Assets
Activity LifecycleLifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Process LifecycleLifecycle
Android keeps application processes around for as long as possible
ndash Even when the activity is closed with V585W`-7 or the back key is pressed
The foreground activity process is considered the most important
ndash It can still be killed as a last resort
Visible activities are also given high priority
ndash Backgrounded activities are considered less important
ndash Processes with no active activities are killed first
Implications of the Process LifecycleLifecycle
Be careful with static initializers
ndash Your library cannot be unloaded while your process is active
bull Donrsquot assume that your static initializers will be run when your activity is created
Be careful with threads
ndash Threads are tied to the process not the activity
bull Your threads will continue to run at reduced priority even if your activity is backgrounded or destroyed
ndash Gameplay should stop during onPause
bull It might make sense to keep certain threads running - your activity may still be visible
ndash Make sure all native code is cleaned up during onDestroy
bull Users expect that your application will no longer be active when its activity is destroyed
The Basics
Key handling
ndash Your device most likely has capacitive buttons
bull Look for complete state transitions of I8m2I_8I8m2AL
bull Avoid overriding 45WLR`m2N8R
ndash Use I8m290R5L0I8m2I8Camp6WW
bull Keep your game behaving like an Android application
TouchMultitouch handling
ndash With I8I9`N8R
bull take advantage of built-in gesture processing
ndash use gt0GWR96RRI6 and GWR96RRI6
ndash Most devices now support multitouch
bull determine if your device can track distinct points
ndash `Wgt2WR1FR96-F$AltA(gtltXAJA(JgtJX)
37
Input
Other Input
Trackball handling
ndash With I86TB00N8R
bull Unhandled events turn into dpad events
Motion handling
ndash With I8gt8WI6`8C4
bull Must be registered with the gt8WI68C6
bull Disable unneeded sensors especially when paused
ndash Active sensors will quickly drain the battery
38
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
OpenGL
GLSurfaceView
ndash Creates the compatible context
bull Contexts are shared between native code and Dalvik
ndash Creates a rendering thread
ndash Releases the context during onPause
ndash Not the most efficient way to multitask withOpenGL but it avoids some driver issues
When context is lost
ndash Reload resources
bull Textures
bull Buffer objects
bull Shaders
ndash Names donrsquot persist
40
Graphics
Texture Formats
Android encourages innovation in hardware
ndash Chipset vendors use several kinds of proprietary texture compression formats
ndash OpenGL ES supports multiple compressed formats none mandatory
Solutions
ndash Uncompressed Textures
ndash Use ETC1 ndash broad support in 20
bull Optimized around photographic data
bull No Alpha
ndash Use Multi-APK (coming soon)
ndash Put textures on an asset server
bull Detect support at runtime
bull Download to each device
41
Graphics
Drawing for Performance
Draw order is important
ndash Has no impact on some platforms means everything on others
ndash Draw front to back to make best use of early rejects
Use VBOs
ndash Avoid unnecessary state changes
Textures
ndash Use power of 2 sized textures
bull It can be very slow
bull On some chipsets not all address modes work
42
Graphics
Writing Compatible Shaders
Query query
ndash Make sure to query for number of attributes varying and uniforms supported
bull Varies between devices
bull Not respecting will make your application crash
bull ldquoSupportedrdquo does not mean ldquoperforms wellrdquo
Conditions
ndash Avoid as much as possible
bull if necessary put them last in the shader
ndash Use mix() clamp() etc to create the same result
discard()
ndash Avoid discard()
bull if necessary it should be last
43
Graphics
Audio Solutions
Full track audio
s 45amp026
bull Plays multiple formats with codec support
bull Plays from filesystem or from network
bull Has high latency memory and CPU usage for quick sound effects
Sound effects and clips
s gtI984ampII0
bull Plays multiple formats with codec support
bull Preloads audio files to a pool
ndash Plays them with low latency
44
Sound
Audio Solutions
Application-generated audio
s $945I6T
bull Plays PCM audio only with minimal latency
bull Useful for applications that wish to perform sound processing or mixing
OpenSLES
ndash Combines capabilities of 45amp026 and $945I6T
ndash Available only in the NDK
ndash Requires Android 23 and higher
45
Sound
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
Use native AssetManager
ndash Gingerbread and Beyond
Targeting tricky trying tasks
Troubleshooting Tips and Tricks
47
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
One JNI Context Per Thread
Threading Options
49
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
JNI Context 2
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
OR
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
If all else fails Market filters
ndash Instruction set
ndash ARMv5ARMv7
ndash GL version
ndash Platform release
ndash Use Device Availability
Tips Standing Out from the Crowd
Start Small
ndash Download assets as-needed
ndash Hook me early instead of making me wait
Use Android backuprestore service (save to the cloud)
ndash Keep my progress when I switch devices
Support multiple control schemes
ndash Trackball D-pad virtual stick
ndash Let me decide what works best
Support install-to-SD
ndash Android Market users will knock your ratings if you donrsquot
51
Tips Standing Out from the Crowd
Profiling
ndash In-game profiling to select optimal settings per-device
Social
ndash Hook into social networks
ndash Use OpenID
Build a live wallpaper
ndash Own the userrsquos home screen with stats avatars
Analytics
ndash Market and in-game
In-app payments
ndash Consider alternative monetization techniques
52
Troubleshooting Development Tools
NVIDIA Debug Manager for Eclipse
ndash Simplifies setup for native debugger under Eclipse
bull developernvidiacomtegranvidia-debug-manager-android-ndk
WinGDB
ndash Use Visual Studio to debug Android NDK applications
bull wwwwingdbcom
vs-android
ndash Native MSBuild files for Android toolchain
bull vs-androidgooglecodecom
53
Troubleshooting Performance Tools
NVIDIA PerfHUD ES
ndash developernvidiacomtegraperfhud-es
Adreno Profiler
ndash developerqualcommcomshowcaseadreno-profiler
POWERVR Insider Utilities
ndash Including PVRTrace and PVRTune
ndash wwwimgteccompowervrinsiderpowervr-utilitiesasp
54
developerandroidcomsdkndkGoogleGameDevAndroid
Feedback httpgooglNudVs
QampA
55
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Development Flow Project Setup
14
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Development Flow Project Setup
14
Created by $amp($))+$)(
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Project Setup
15
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Project Setup
15
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Created Manually
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Set up project
Write makefiles
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
$ampampampltPamp$(+)+-00+1234567QL6IER$ampampAgt++++++)+05BC0DE85$ampampampJ++++++++)+4B9C$ampamp$MJ++++++++++)+61B5+61B53NS
APP_STL = gnustl_static
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
$ampampampltPamp$(+)+-00+1234567QL6IER$ampampAgt++++++)+05BC0DE85$ampampampJ++++++++)+4B9C$ampamp$MJ++++++++++)+61B5+61B53NS
APP_STL = gnustl_static
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Interface Classes
Write interface in Java
ndash Use amp) keyword
17
LTC+I1K846I54KC0DE85U
QQ+H6LL6+VI6+8R5N+05B662
L9B05+0WW+GDPXJ5B+YR84W+$R5N5R2+Z
++WRR5+Z++++gt2WR1K0I45B662-[C0DE85[7U++
++Q]]+++]+^L61+_54R`+R`+9668R+N5_+_54R`+++]+^L61+`5C`R+R`+9668R+N5_+`5C`R+++]Q+++L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7U+++L9B05+WRR5+8R5N+NI54+WRL-7U
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
PXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]LPXJ8Na+EIBER+IBEa+E58R+a+E58R+B7+Z
++E0WW+0W++-]LPXJ8N73dGRBER0WW-LPXJ8Na+IBE7U
++E1R`I4J+54++-]LPXJ8N73dGRR`I4J-+++++++++++++++++++++++++++++LPXJ8Na+0Wa+[RTm2N8RW[a+[-n7=[7U
++-]LPXJ8N73d00=I54R`I4-LPXJ8Na+IBEa+54a+PXJltA7U
Development Flow Calling Dalvik Code Within CC++
20
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Build and Deploy
gt=0Alt-amp49BCDBEFG6HI
ndash Builds C libraries and emits so files
gt)-3
ndash (or ant release)
ndash Builds Java classes apk package
gtamp=44
ndash Deploys to emulator or device
21
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdbgdb-rsp over named pipe
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdb
EclipseVS
gdb-rsp over named pipe
gdb-MI
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Important Tip
B)-36amp3)$$)J23
Bringing Your Game to Android
24
Devices Accessing Android Market
25
Android 16
Android 15
Android 23
Android 233
Android 30
Two Week Period Published May 2011
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
NativeActivity is just starting
ndash 43 of checking-in devices can utilize it
ndash For non-tablet-specific titles we can take advantage of NativeActivity without becoming incompatible
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Platform-specific Resources
Using NativeActivity Compatibly
27
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dV0WcQBII0d++++cBII0+81[8IRG58C6B64[dR69cQBII0dcQ6WI96Wd
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dR69cQBII0d++++cBII0+81[8IRG58C6B64[dV0WcQBII0dcQ6WI96Wd
Using NativeActivity Compatibly
28
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
cR5N5R2+846I54)81[Kgt$XR5N$R5N5R2[+++846I54)8B04[^BII0QRWRG58C6B64[d++c1R34R+846I54)81[846I54KLLK05B81[+++++846I54)N09[W8R5N[+Qd++++++++++++++++++++++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6d++++++++++++cQR5N5R2dcR5N5R2+846I54)81[K1I$R5N5R2[+++846I54)8B04[^BII0Q8IRG58C6B64[d++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6dcQR5N5R2d
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+W8R5N$F$Ggt+)+3$XltJXm$gtltFJgt+ )+C09R50WK+k+ LL3846I5438R5NK$JMgt+)+30GgtND+3040+300IC+30G+30846I54$gt$JJMlt$ltJgt+ )+846I548R5NLLC09$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7-00+51LI6R31I490a846I54Q8R5NLLC097
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
LTC+I1KY1L0KW88C0WU
L9B05+0WW+gt$XR5N$R5N5R2+YR84W+846I54KLLKXR5N$R5N5R2+Z
++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
LTC+I1KY1L0KW88C0WU
L9B05+0WW+1I$R5N5R2+YR84W+846I54KLLK$R5N5R2+Z++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++++++gt2WR1K0I45B662-[WE85[7U++++KKK
Key Game Components
33
Lifecycle
Graphics Sound
Input
Assets
Activity LifecycleLifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Process LifecycleLifecycle
Android keeps application processes around for as long as possible
ndash Even when the activity is closed with V585W`-7 or the back key is pressed
The foreground activity process is considered the most important
ndash It can still be killed as a last resort
Visible activities are also given high priority
ndash Backgrounded activities are considered less important
ndash Processes with no active activities are killed first
Implications of the Process LifecycleLifecycle
Be careful with static initializers
ndash Your library cannot be unloaded while your process is active
bull Donrsquot assume that your static initializers will be run when your activity is created
Be careful with threads
ndash Threads are tied to the process not the activity
bull Your threads will continue to run at reduced priority even if your activity is backgrounded or destroyed
ndash Gameplay should stop during onPause
bull It might make sense to keep certain threads running - your activity may still be visible
ndash Make sure all native code is cleaned up during onDestroy
bull Users expect that your application will no longer be active when its activity is destroyed
The Basics
Key handling
ndash Your device most likely has capacitive buttons
bull Look for complete state transitions of I8m2I_8I8m2AL
bull Avoid overriding 45WLR`m2N8R
ndash Use I8m290R5L0I8m2I8Camp6WW
bull Keep your game behaving like an Android application
TouchMultitouch handling
ndash With I8I9`N8R
bull take advantage of built-in gesture processing
ndash use gt0GWR96RRI6 and GWR96RRI6
ndash Most devices now support multitouch
bull determine if your device can track distinct points
ndash `Wgt2WR1FR96-F$AltA(gtltXAJA(JgtJX)
37
Input
Other Input
Trackball handling
ndash With I86TB00N8R
bull Unhandled events turn into dpad events
Motion handling
ndash With I8gt8WI6`8C4
bull Must be registered with the gt8WI68C6
bull Disable unneeded sensors especially when paused
ndash Active sensors will quickly drain the battery
38
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
OpenGL
GLSurfaceView
ndash Creates the compatible context
bull Contexts are shared between native code and Dalvik
ndash Creates a rendering thread
ndash Releases the context during onPause
ndash Not the most efficient way to multitask withOpenGL but it avoids some driver issues
When context is lost
ndash Reload resources
bull Textures
bull Buffer objects
bull Shaders
ndash Names donrsquot persist
40
Graphics
Texture Formats
Android encourages innovation in hardware
ndash Chipset vendors use several kinds of proprietary texture compression formats
ndash OpenGL ES supports multiple compressed formats none mandatory
Solutions
ndash Uncompressed Textures
ndash Use ETC1 ndash broad support in 20
bull Optimized around photographic data
bull No Alpha
ndash Use Multi-APK (coming soon)
ndash Put textures on an asset server
bull Detect support at runtime
bull Download to each device
41
Graphics
Drawing for Performance
Draw order is important
ndash Has no impact on some platforms means everything on others
ndash Draw front to back to make best use of early rejects
Use VBOs
ndash Avoid unnecessary state changes
Textures
ndash Use power of 2 sized textures
bull It can be very slow
bull On some chipsets not all address modes work
42
Graphics
Writing Compatible Shaders
Query query
ndash Make sure to query for number of attributes varying and uniforms supported
bull Varies between devices
bull Not respecting will make your application crash
bull ldquoSupportedrdquo does not mean ldquoperforms wellrdquo
Conditions
ndash Avoid as much as possible
bull if necessary put them last in the shader
ndash Use mix() clamp() etc to create the same result
discard()
ndash Avoid discard()
bull if necessary it should be last
43
Graphics
Audio Solutions
Full track audio
s 45amp026
bull Plays multiple formats with codec support
bull Plays from filesystem or from network
bull Has high latency memory and CPU usage for quick sound effects
Sound effects and clips
s gtI984ampII0
bull Plays multiple formats with codec support
bull Preloads audio files to a pool
ndash Plays them with low latency
44
Sound
Audio Solutions
Application-generated audio
s $945I6T
bull Plays PCM audio only with minimal latency
bull Useful for applications that wish to perform sound processing or mixing
OpenSLES
ndash Combines capabilities of 45amp026 and $945I6T
ndash Available only in the NDK
ndash Requires Android 23 and higher
45
Sound
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
Use native AssetManager
ndash Gingerbread and Beyond
Targeting tricky trying tasks
Troubleshooting Tips and Tricks
47
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
One JNI Context Per Thread
Threading Options
49
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
JNI Context 2
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
OR
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
If all else fails Market filters
ndash Instruction set
ndash ARMv5ARMv7
ndash GL version
ndash Platform release
ndash Use Device Availability
Tips Standing Out from the Crowd
Start Small
ndash Download assets as-needed
ndash Hook me early instead of making me wait
Use Android backuprestore service (save to the cloud)
ndash Keep my progress when I switch devices
Support multiple control schemes
ndash Trackball D-pad virtual stick
ndash Let me decide what works best
Support install-to-SD
ndash Android Market users will knock your ratings if you donrsquot
51
Tips Standing Out from the Crowd
Profiling
ndash In-game profiling to select optimal settings per-device
Social
ndash Hook into social networks
ndash Use OpenID
Build a live wallpaper
ndash Own the userrsquos home screen with stats avatars
Analytics
ndash Market and in-game
In-app payments
ndash Consider alternative monetization techniques
52
Troubleshooting Development Tools
NVIDIA Debug Manager for Eclipse
ndash Simplifies setup for native debugger under Eclipse
bull developernvidiacomtegranvidia-debug-manager-android-ndk
WinGDB
ndash Use Visual Studio to debug Android NDK applications
bull wwwwingdbcom
vs-android
ndash Native MSBuild files for Android toolchain
bull vs-androidgooglecodecom
53
Troubleshooting Performance Tools
NVIDIA PerfHUD ES
ndash developernvidiacomtegraperfhud-es
Adreno Profiler
ndash developerqualcommcomshowcaseadreno-profiler
POWERVR Insider Utilities
ndash Including PVRTrace and PVRTune
ndash wwwimgteccompowervrinsiderpowervr-utilitiesasp
54
developerandroidcomsdkndkGoogleGameDevAndroid
Feedback httpgooglNudVs
QampA
55
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Development Flow Project Setup
14
Created by $amp($))+$)(
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Project Setup
15
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Project Setup
15
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Created Manually
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Set up project
Write makefiles
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
$ampampampltPamp$(+)+-00+1234567QL6IER$ampampAgt++++++)+05BC0DE85$ampampampJ++++++++)+4B9C$ampamp$MJ++++++++++)+61B5+61B53NS
APP_STL = gnustl_static
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
$ampampampltPamp$(+)+-00+1234567QL6IER$ampampAgt++++++)+05BC0DE85$ampampampJ++++++++)+4B9C$ampamp$MJ++++++++++)+61B5+61B53NS
APP_STL = gnustl_static
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Interface Classes
Write interface in Java
ndash Use amp) keyword
17
LTC+I1K846I54KC0DE85U
QQ+H6LL6+VI6+8R5N+05B662
L9B05+0WW+GDPXJ5B+YR84W+$R5N5R2+Z
++WRR5+Z++++gt2WR1K0I45B662-[C0DE85[7U++
++Q]]+++]+^L61+_54R`+R`+9668R+N5_+_54R`+++]+^L61+`5C`R+R`+9668R+N5_+`5C`R+++]Q+++L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7U+++L9B05+WRR5+8R5N+NI54+WRL-7U
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
PXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]LPXJ8Na+EIBER+IBEa+E58R+a+E58R+B7+Z
++E0WW+0W++-]LPXJ8N73dGRBER0WW-LPXJ8Na+IBE7U
++E1R`I4J+54++-]LPXJ8N73dGRR`I4J-+++++++++++++++++++++++++++++LPXJ8Na+0Wa+[RTm2N8RW[a+[-n7=[7U
++-]LPXJ8N73d00=I54R`I4-LPXJ8Na+IBEa+54a+PXJltA7U
Development Flow Calling Dalvik Code Within CC++
20
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Build and Deploy
gt=0Alt-amp49BCDBEFG6HI
ndash Builds C libraries and emits so files
gt)-3
ndash (or ant release)
ndash Builds Java classes apk package
gtamp=44
ndash Deploys to emulator or device
21
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdbgdb-rsp over named pipe
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdb
EclipseVS
gdb-rsp over named pipe
gdb-MI
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Important Tip
B)-36amp3)$$)J23
Bringing Your Game to Android
24
Devices Accessing Android Market
25
Android 16
Android 15
Android 23
Android 233
Android 30
Two Week Period Published May 2011
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
NativeActivity is just starting
ndash 43 of checking-in devices can utilize it
ndash For non-tablet-specific titles we can take advantage of NativeActivity without becoming incompatible
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Platform-specific Resources
Using NativeActivity Compatibly
27
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dV0WcQBII0d++++cBII0+81[8IRG58C6B64[dR69cQBII0dcQ6WI96Wd
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dR69cQBII0d++++cBII0+81[8IRG58C6B64[dV0WcQBII0dcQ6WI96Wd
Using NativeActivity Compatibly
28
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
cR5N5R2+846I54)81[Kgt$XR5N$R5N5R2[+++846I54)8B04[^BII0QRWRG58C6B64[d++c1R34R+846I54)81[846I54KLLK05B81[+++++846I54)N09[W8R5N[+Qd++++++++++++++++++++++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6d++++++++++++cQR5N5R2dcR5N5R2+846I54)81[K1I$R5N5R2[+++846I54)8B04[^BII0Q8IRG58C6B64[d++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6dcQR5N5R2d
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+W8R5N$F$Ggt+)+3$XltJXm$gtltFJgt+ )+C09R50WK+k+ LL3846I5438R5NK$JMgt+)+30GgtND+3040+300IC+30G+30846I54$gt$JJMlt$ltJgt+ )+846I548R5NLLC09$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7-00+51LI6R31I490a846I54Q8R5NLLC097
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
LTC+I1KY1L0KW88C0WU
L9B05+0WW+gt$XR5N$R5N5R2+YR84W+846I54KLLKXR5N$R5N5R2+Z
++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
LTC+I1KY1L0KW88C0WU
L9B05+0WW+1I$R5N5R2+YR84W+846I54KLLK$R5N5R2+Z++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++++++gt2WR1K0I45B662-[WE85[7U++++KKK
Key Game Components
33
Lifecycle
Graphics Sound
Input
Assets
Activity LifecycleLifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Process LifecycleLifecycle
Android keeps application processes around for as long as possible
ndash Even when the activity is closed with V585W`-7 or the back key is pressed
The foreground activity process is considered the most important
ndash It can still be killed as a last resort
Visible activities are also given high priority
ndash Backgrounded activities are considered less important
ndash Processes with no active activities are killed first
Implications of the Process LifecycleLifecycle
Be careful with static initializers
ndash Your library cannot be unloaded while your process is active
bull Donrsquot assume that your static initializers will be run when your activity is created
Be careful with threads
ndash Threads are tied to the process not the activity
bull Your threads will continue to run at reduced priority even if your activity is backgrounded or destroyed
ndash Gameplay should stop during onPause
bull It might make sense to keep certain threads running - your activity may still be visible
ndash Make sure all native code is cleaned up during onDestroy
bull Users expect that your application will no longer be active when its activity is destroyed
The Basics
Key handling
ndash Your device most likely has capacitive buttons
bull Look for complete state transitions of I8m2I_8I8m2AL
bull Avoid overriding 45WLR`m2N8R
ndash Use I8m290R5L0I8m2I8Camp6WW
bull Keep your game behaving like an Android application
TouchMultitouch handling
ndash With I8I9`N8R
bull take advantage of built-in gesture processing
ndash use gt0GWR96RRI6 and GWR96RRI6
ndash Most devices now support multitouch
bull determine if your device can track distinct points
ndash `Wgt2WR1FR96-F$AltA(gtltXAJA(JgtJX)
37
Input
Other Input
Trackball handling
ndash With I86TB00N8R
bull Unhandled events turn into dpad events
Motion handling
ndash With I8gt8WI6`8C4
bull Must be registered with the gt8WI68C6
bull Disable unneeded sensors especially when paused
ndash Active sensors will quickly drain the battery
38
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
OpenGL
GLSurfaceView
ndash Creates the compatible context
bull Contexts are shared between native code and Dalvik
ndash Creates a rendering thread
ndash Releases the context during onPause
ndash Not the most efficient way to multitask withOpenGL but it avoids some driver issues
When context is lost
ndash Reload resources
bull Textures
bull Buffer objects
bull Shaders
ndash Names donrsquot persist
40
Graphics
Texture Formats
Android encourages innovation in hardware
ndash Chipset vendors use several kinds of proprietary texture compression formats
ndash OpenGL ES supports multiple compressed formats none mandatory
Solutions
ndash Uncompressed Textures
ndash Use ETC1 ndash broad support in 20
bull Optimized around photographic data
bull No Alpha
ndash Use Multi-APK (coming soon)
ndash Put textures on an asset server
bull Detect support at runtime
bull Download to each device
41
Graphics
Drawing for Performance
Draw order is important
ndash Has no impact on some platforms means everything on others
ndash Draw front to back to make best use of early rejects
Use VBOs
ndash Avoid unnecessary state changes
Textures
ndash Use power of 2 sized textures
bull It can be very slow
bull On some chipsets not all address modes work
42
Graphics
Writing Compatible Shaders
Query query
ndash Make sure to query for number of attributes varying and uniforms supported
bull Varies between devices
bull Not respecting will make your application crash
bull ldquoSupportedrdquo does not mean ldquoperforms wellrdquo
Conditions
ndash Avoid as much as possible
bull if necessary put them last in the shader
ndash Use mix() clamp() etc to create the same result
discard()
ndash Avoid discard()
bull if necessary it should be last
43
Graphics
Audio Solutions
Full track audio
s 45amp026
bull Plays multiple formats with codec support
bull Plays from filesystem or from network
bull Has high latency memory and CPU usage for quick sound effects
Sound effects and clips
s gtI984ampII0
bull Plays multiple formats with codec support
bull Preloads audio files to a pool
ndash Plays them with low latency
44
Sound
Audio Solutions
Application-generated audio
s $945I6T
bull Plays PCM audio only with minimal latency
bull Useful for applications that wish to perform sound processing or mixing
OpenSLES
ndash Combines capabilities of 45amp026 and $945I6T
ndash Available only in the NDK
ndash Requires Android 23 and higher
45
Sound
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
Use native AssetManager
ndash Gingerbread and Beyond
Targeting tricky trying tasks
Troubleshooting Tips and Tricks
47
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
One JNI Context Per Thread
Threading Options
49
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
JNI Context 2
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
OR
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
If all else fails Market filters
ndash Instruction set
ndash ARMv5ARMv7
ndash GL version
ndash Platform release
ndash Use Device Availability
Tips Standing Out from the Crowd
Start Small
ndash Download assets as-needed
ndash Hook me early instead of making me wait
Use Android backuprestore service (save to the cloud)
ndash Keep my progress when I switch devices
Support multiple control schemes
ndash Trackball D-pad virtual stick
ndash Let me decide what works best
Support install-to-SD
ndash Android Market users will knock your ratings if you donrsquot
51
Tips Standing Out from the Crowd
Profiling
ndash In-game profiling to select optimal settings per-device
Social
ndash Hook into social networks
ndash Use OpenID
Build a live wallpaper
ndash Own the userrsquos home screen with stats avatars
Analytics
ndash Market and in-game
In-app payments
ndash Consider alternative monetization techniques
52
Troubleshooting Development Tools
NVIDIA Debug Manager for Eclipse
ndash Simplifies setup for native debugger under Eclipse
bull developernvidiacomtegranvidia-debug-manager-android-ndk
WinGDB
ndash Use Visual Studio to debug Android NDK applications
bull wwwwingdbcom
vs-android
ndash Native MSBuild files for Android toolchain
bull vs-androidgooglecodecom
53
Troubleshooting Performance Tools
NVIDIA PerfHUD ES
ndash developernvidiacomtegraperfhud-es
Adreno Profiler
ndash developerqualcommcomshowcaseadreno-profiler
POWERVR Insider Utilities
ndash Including PVRTrace and PVRTune
ndash wwwimgteccompowervrinsiderpowervr-utilitiesasp
54
developerandroidcomsdkndkGoogleGameDevAndroid
Feedback httpgooglNudVs
QampA
55
Development Flow Project Setup
15
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Project Setup
15
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Created Manually
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Set up project
Write makefiles
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
$ampampampltPamp$(+)+-00+1234567QL6IER$ampampAgt++++++)+05BC0DE85$ampampampJ++++++++)+4B9C$ampamp$MJ++++++++++)+61B5+61B53NS
APP_STL = gnustl_static
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
$ampampampltPamp$(+)+-00+1234567QL6IER$ampampAgt++++++)+05BC0DE85$ampampampJ++++++++)+4B9C$ampamp$MJ++++++++++)+61B5+61B53NS
APP_STL = gnustl_static
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Interface Classes
Write interface in Java
ndash Use amp) keyword
17
LTC+I1K846I54KC0DE85U
QQ+H6LL6+VI6+8R5N+05B662
L9B05+0WW+GDPXJ5B+YR84W+$R5N5R2+Z
++WRR5+Z++++gt2WR1K0I45B662-[C0DE85[7U++
++Q]]+++]+^L61+_54R`+R`+9668R+N5_+_54R`+++]+^L61+`5C`R+R`+9668R+N5_+`5C`R+++]Q+++L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7U+++L9B05+WRR5+8R5N+NI54+WRL-7U
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
PXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]LPXJ8Na+EIBER+IBEa+E58R+a+E58R+B7+Z
++E0WW+0W++-]LPXJ8N73dGRBER0WW-LPXJ8Na+IBE7U
++E1R`I4J+54++-]LPXJ8N73dGRR`I4J-+++++++++++++++++++++++++++++LPXJ8Na+0Wa+[RTm2N8RW[a+[-n7=[7U
++-]LPXJ8N73d00=I54R`I4-LPXJ8Na+IBEa+54a+PXJltA7U
Development Flow Calling Dalvik Code Within CC++
20
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Build and Deploy
gt=0Alt-amp49BCDBEFG6HI
ndash Builds C libraries and emits so files
gt)-3
ndash (or ant release)
ndash Builds Java classes apk package
gtamp=44
ndash Deploys to emulator or device
21
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdbgdb-rsp over named pipe
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdb
EclipseVS
gdb-rsp over named pipe
gdb-MI
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Important Tip
B)-36amp3)$$)J23
Bringing Your Game to Android
24
Devices Accessing Android Market
25
Android 16
Android 15
Android 23
Android 233
Android 30
Two Week Period Published May 2011
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
NativeActivity is just starting
ndash 43 of checking-in devices can utilize it
ndash For non-tablet-specific titles we can take advantage of NativeActivity without becoming incompatible
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Platform-specific Resources
Using NativeActivity Compatibly
27
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dV0WcQBII0d++++cBII0+81[8IRG58C6B64[dR69cQBII0dcQ6WI96Wd
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dR69cQBII0d++++cBII0+81[8IRG58C6B64[dV0WcQBII0dcQ6WI96Wd
Using NativeActivity Compatibly
28
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
cR5N5R2+846I54)81[Kgt$XR5N$R5N5R2[+++846I54)8B04[^BII0QRWRG58C6B64[d++c1R34R+846I54)81[846I54KLLK05B81[+++++846I54)N09[W8R5N[+Qd++++++++++++++++++++++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6d++++++++++++cQR5N5R2dcR5N5R2+846I54)81[K1I$R5N5R2[+++846I54)8B04[^BII0Q8IRG58C6B64[d++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6dcQR5N5R2d
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+W8R5N$F$Ggt+)+3$XltJXm$gtltFJgt+ )+C09R50WK+k+ LL3846I5438R5NK$JMgt+)+30GgtND+3040+300IC+30G+30846I54$gt$JJMlt$ltJgt+ )+846I548R5NLLC09$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7-00+51LI6R31I490a846I54Q8R5NLLC097
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
LTC+I1KY1L0KW88C0WU
L9B05+0WW+gt$XR5N$R5N5R2+YR84W+846I54KLLKXR5N$R5N5R2+Z
++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
LTC+I1KY1L0KW88C0WU
L9B05+0WW+1I$R5N5R2+YR84W+846I54KLLK$R5N5R2+Z++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++++++gt2WR1K0I45B662-[WE85[7U++++KKK
Key Game Components
33
Lifecycle
Graphics Sound
Input
Assets
Activity LifecycleLifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Process LifecycleLifecycle
Android keeps application processes around for as long as possible
ndash Even when the activity is closed with V585W`-7 or the back key is pressed
The foreground activity process is considered the most important
ndash It can still be killed as a last resort
Visible activities are also given high priority
ndash Backgrounded activities are considered less important
ndash Processes with no active activities are killed first
Implications of the Process LifecycleLifecycle
Be careful with static initializers
ndash Your library cannot be unloaded while your process is active
bull Donrsquot assume that your static initializers will be run when your activity is created
Be careful with threads
ndash Threads are tied to the process not the activity
bull Your threads will continue to run at reduced priority even if your activity is backgrounded or destroyed
ndash Gameplay should stop during onPause
bull It might make sense to keep certain threads running - your activity may still be visible
ndash Make sure all native code is cleaned up during onDestroy
bull Users expect that your application will no longer be active when its activity is destroyed
The Basics
Key handling
ndash Your device most likely has capacitive buttons
bull Look for complete state transitions of I8m2I_8I8m2AL
bull Avoid overriding 45WLR`m2N8R
ndash Use I8m290R5L0I8m2I8Camp6WW
bull Keep your game behaving like an Android application
TouchMultitouch handling
ndash With I8I9`N8R
bull take advantage of built-in gesture processing
ndash use gt0GWR96RRI6 and GWR96RRI6
ndash Most devices now support multitouch
bull determine if your device can track distinct points
ndash `Wgt2WR1FR96-F$AltA(gtltXAJA(JgtJX)
37
Input
Other Input
Trackball handling
ndash With I86TB00N8R
bull Unhandled events turn into dpad events
Motion handling
ndash With I8gt8WI6`8C4
bull Must be registered with the gt8WI68C6
bull Disable unneeded sensors especially when paused
ndash Active sensors will quickly drain the battery
38
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
OpenGL
GLSurfaceView
ndash Creates the compatible context
bull Contexts are shared between native code and Dalvik
ndash Creates a rendering thread
ndash Releases the context during onPause
ndash Not the most efficient way to multitask withOpenGL but it avoids some driver issues
When context is lost
ndash Reload resources
bull Textures
bull Buffer objects
bull Shaders
ndash Names donrsquot persist
40
Graphics
Texture Formats
Android encourages innovation in hardware
ndash Chipset vendors use several kinds of proprietary texture compression formats
ndash OpenGL ES supports multiple compressed formats none mandatory
Solutions
ndash Uncompressed Textures
ndash Use ETC1 ndash broad support in 20
bull Optimized around photographic data
bull No Alpha
ndash Use Multi-APK (coming soon)
ndash Put textures on an asset server
bull Detect support at runtime
bull Download to each device
41
Graphics
Drawing for Performance
Draw order is important
ndash Has no impact on some platforms means everything on others
ndash Draw front to back to make best use of early rejects
Use VBOs
ndash Avoid unnecessary state changes
Textures
ndash Use power of 2 sized textures
bull It can be very slow
bull On some chipsets not all address modes work
42
Graphics
Writing Compatible Shaders
Query query
ndash Make sure to query for number of attributes varying and uniforms supported
bull Varies between devices
bull Not respecting will make your application crash
bull ldquoSupportedrdquo does not mean ldquoperforms wellrdquo
Conditions
ndash Avoid as much as possible
bull if necessary put them last in the shader
ndash Use mix() clamp() etc to create the same result
discard()
ndash Avoid discard()
bull if necessary it should be last
43
Graphics
Audio Solutions
Full track audio
s 45amp026
bull Plays multiple formats with codec support
bull Plays from filesystem or from network
bull Has high latency memory and CPU usage for quick sound effects
Sound effects and clips
s gtI984ampII0
bull Plays multiple formats with codec support
bull Preloads audio files to a pool
ndash Plays them with low latency
44
Sound
Audio Solutions
Application-generated audio
s $945I6T
bull Plays PCM audio only with minimal latency
bull Useful for applications that wish to perform sound processing or mixing
OpenSLES
ndash Combines capabilities of 45amp026 and $945I6T
ndash Available only in the NDK
ndash Requires Android 23 and higher
45
Sound
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
Use native AssetManager
ndash Gingerbread and Beyond
Targeting tricky trying tasks
Troubleshooting Tips and Tricks
47
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
One JNI Context Per Thread
Threading Options
49
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
JNI Context 2
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
OR
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
If all else fails Market filters
ndash Instruction set
ndash ARMv5ARMv7
ndash GL version
ndash Platform release
ndash Use Device Availability
Tips Standing Out from the Crowd
Start Small
ndash Download assets as-needed
ndash Hook me early instead of making me wait
Use Android backuprestore service (save to the cloud)
ndash Keep my progress when I switch devices
Support multiple control schemes
ndash Trackball D-pad virtual stick
ndash Let me decide what works best
Support install-to-SD
ndash Android Market users will knock your ratings if you donrsquot
51
Tips Standing Out from the Crowd
Profiling
ndash In-game profiling to select optimal settings per-device
Social
ndash Hook into social networks
ndash Use OpenID
Build a live wallpaper
ndash Own the userrsquos home screen with stats avatars
Analytics
ndash Market and in-game
In-app payments
ndash Consider alternative monetization techniques
52
Troubleshooting Development Tools
NVIDIA Debug Manager for Eclipse
ndash Simplifies setup for native debugger under Eclipse
bull developernvidiacomtegranvidia-debug-manager-android-ndk
WinGDB
ndash Use Visual Studio to debug Android NDK applications
bull wwwwingdbcom
vs-android
ndash Native MSBuild files for Android toolchain
bull vs-androidgooglecodecom
53
Troubleshooting Performance Tools
NVIDIA PerfHUD ES
ndash developernvidiacomtegraperfhud-es
Adreno Profiler
ndash developerqualcommcomshowcaseadreno-profiler
POWERVR Insider Utilities
ndash Including PVRTrace and PVRTune
ndash wwwimgteccompowervrinsiderpowervr-utilitiesasp
54
developerandroidcomsdkndkGoogleGameDevAndroid
Feedback httpgooglNudVs
QampA
55
Development Flow Project Setup
15
Run $amp($))+$)(
ndash Ant script
ndash Common directories
ndash Resources
ndash Per-machine settings
OR $amp-+)+$)(
ndash For existing code
Created Manually
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Set up project
Write makefiles
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
$ampampampltPamp$(+)+-00+1234567QL6IER$ampampAgt++++++)+05BC0DE85$ampampampJ++++++++)+4B9C$ampamp$MJ++++++++++)+61B5+61B53NS
APP_STL = gnustl_static
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
$ampampampltPamp$(+)+-00+1234567QL6IER$ampampAgt++++++)+05BC0DE85$ampampampJ++++++++)+4B9C$ampamp$MJ++++++++++)+61B5+61B53NS
APP_STL = gnustl_static
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Interface Classes
Write interface in Java
ndash Use amp) keyword
17
LTC+I1K846I54KC0DE85U
QQ+H6LL6+VI6+8R5N+05B662
L9B05+0WW+GDPXJ5B+YR84W+$R5N5R2+Z
++WRR5+Z++++gt2WR1K0I45B662-[C0DE85[7U++
++Q]]+++]+^L61+_54R`+R`+9668R+N5_+_54R`+++]+^L61+`5C`R+R`+9668R+N5_+`5C`R+++]Q+++L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7U+++L9B05+WRR5+8R5N+NI54+WRL-7U
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
PXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]LPXJ8Na+EIBER+IBEa+E58R+a+E58R+B7+Z
++E0WW+0W++-]LPXJ8N73dGRBER0WW-LPXJ8Na+IBE7U
++E1R`I4J+54++-]LPXJ8N73dGRR`I4J-+++++++++++++++++++++++++++++LPXJ8Na+0Wa+[RTm2N8RW[a+[-n7=[7U
++-]LPXJ8N73d00=I54R`I4-LPXJ8Na+IBEa+54a+PXJltA7U
Development Flow Calling Dalvik Code Within CC++
20
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Build and Deploy
gt=0Alt-amp49BCDBEFG6HI
ndash Builds C libraries and emits so files
gt)-3
ndash (or ant release)
ndash Builds Java classes apk package
gtamp=44
ndash Deploys to emulator or device
21
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdbgdb-rsp over named pipe
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdb
EclipseVS
gdb-rsp over named pipe
gdb-MI
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Important Tip
B)-36amp3)$$)J23
Bringing Your Game to Android
24
Devices Accessing Android Market
25
Android 16
Android 15
Android 23
Android 233
Android 30
Two Week Period Published May 2011
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
NativeActivity is just starting
ndash 43 of checking-in devices can utilize it
ndash For non-tablet-specific titles we can take advantage of NativeActivity without becoming incompatible
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Platform-specific Resources
Using NativeActivity Compatibly
27
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dV0WcQBII0d++++cBII0+81[8IRG58C6B64[dR69cQBII0dcQ6WI96Wd
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dR69cQBII0d++++cBII0+81[8IRG58C6B64[dV0WcQBII0dcQ6WI96Wd
Using NativeActivity Compatibly
28
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
cR5N5R2+846I54)81[Kgt$XR5N$R5N5R2[+++846I54)8B04[^BII0QRWRG58C6B64[d++c1R34R+846I54)81[846I54KLLK05B81[+++++846I54)N09[W8R5N[+Qd++++++++++++++++++++++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6d++++++++++++cQR5N5R2dcR5N5R2+846I54)81[K1I$R5N5R2[+++846I54)8B04[^BII0Q8IRG58C6B64[d++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6dcQR5N5R2d
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+W8R5N$F$Ggt+)+3$XltJXm$gtltFJgt+ )+C09R50WK+k+ LL3846I5438R5NK$JMgt+)+30GgtND+3040+300IC+30G+30846I54$gt$JJMlt$ltJgt+ )+846I548R5NLLC09$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7-00+51LI6R31I490a846I54Q8R5NLLC097
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
LTC+I1KY1L0KW88C0WU
L9B05+0WW+gt$XR5N$R5N5R2+YR84W+846I54KLLKXR5N$R5N5R2+Z
++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
LTC+I1KY1L0KW88C0WU
L9B05+0WW+1I$R5N5R2+YR84W+846I54KLLK$R5N5R2+Z++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++++++gt2WR1K0I45B662-[WE85[7U++++KKK
Key Game Components
33
Lifecycle
Graphics Sound
Input
Assets
Activity LifecycleLifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Process LifecycleLifecycle
Android keeps application processes around for as long as possible
ndash Even when the activity is closed with V585W`-7 or the back key is pressed
The foreground activity process is considered the most important
ndash It can still be killed as a last resort
Visible activities are also given high priority
ndash Backgrounded activities are considered less important
ndash Processes with no active activities are killed first
Implications of the Process LifecycleLifecycle
Be careful with static initializers
ndash Your library cannot be unloaded while your process is active
bull Donrsquot assume that your static initializers will be run when your activity is created
Be careful with threads
ndash Threads are tied to the process not the activity
bull Your threads will continue to run at reduced priority even if your activity is backgrounded or destroyed
ndash Gameplay should stop during onPause
bull It might make sense to keep certain threads running - your activity may still be visible
ndash Make sure all native code is cleaned up during onDestroy
bull Users expect that your application will no longer be active when its activity is destroyed
The Basics
Key handling
ndash Your device most likely has capacitive buttons
bull Look for complete state transitions of I8m2I_8I8m2AL
bull Avoid overriding 45WLR`m2N8R
ndash Use I8m290R5L0I8m2I8Camp6WW
bull Keep your game behaving like an Android application
TouchMultitouch handling
ndash With I8I9`N8R
bull take advantage of built-in gesture processing
ndash use gt0GWR96RRI6 and GWR96RRI6
ndash Most devices now support multitouch
bull determine if your device can track distinct points
ndash `Wgt2WR1FR96-F$AltA(gtltXAJA(JgtJX)
37
Input
Other Input
Trackball handling
ndash With I86TB00N8R
bull Unhandled events turn into dpad events
Motion handling
ndash With I8gt8WI6`8C4
bull Must be registered with the gt8WI68C6
bull Disable unneeded sensors especially when paused
ndash Active sensors will quickly drain the battery
38
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
OpenGL
GLSurfaceView
ndash Creates the compatible context
bull Contexts are shared between native code and Dalvik
ndash Creates a rendering thread
ndash Releases the context during onPause
ndash Not the most efficient way to multitask withOpenGL but it avoids some driver issues
When context is lost
ndash Reload resources
bull Textures
bull Buffer objects
bull Shaders
ndash Names donrsquot persist
40
Graphics
Texture Formats
Android encourages innovation in hardware
ndash Chipset vendors use several kinds of proprietary texture compression formats
ndash OpenGL ES supports multiple compressed formats none mandatory
Solutions
ndash Uncompressed Textures
ndash Use ETC1 ndash broad support in 20
bull Optimized around photographic data
bull No Alpha
ndash Use Multi-APK (coming soon)
ndash Put textures on an asset server
bull Detect support at runtime
bull Download to each device
41
Graphics
Drawing for Performance
Draw order is important
ndash Has no impact on some platforms means everything on others
ndash Draw front to back to make best use of early rejects
Use VBOs
ndash Avoid unnecessary state changes
Textures
ndash Use power of 2 sized textures
bull It can be very slow
bull On some chipsets not all address modes work
42
Graphics
Writing Compatible Shaders
Query query
ndash Make sure to query for number of attributes varying and uniforms supported
bull Varies between devices
bull Not respecting will make your application crash
bull ldquoSupportedrdquo does not mean ldquoperforms wellrdquo
Conditions
ndash Avoid as much as possible
bull if necessary put them last in the shader
ndash Use mix() clamp() etc to create the same result
discard()
ndash Avoid discard()
bull if necessary it should be last
43
Graphics
Audio Solutions
Full track audio
s 45amp026
bull Plays multiple formats with codec support
bull Plays from filesystem or from network
bull Has high latency memory and CPU usage for quick sound effects
Sound effects and clips
s gtI984ampII0
bull Plays multiple formats with codec support
bull Preloads audio files to a pool
ndash Plays them with low latency
44
Sound
Audio Solutions
Application-generated audio
s $945I6T
bull Plays PCM audio only with minimal latency
bull Useful for applications that wish to perform sound processing or mixing
OpenSLES
ndash Combines capabilities of 45amp026 and $945I6T
ndash Available only in the NDK
ndash Requires Android 23 and higher
45
Sound
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
Use native AssetManager
ndash Gingerbread and Beyond
Targeting tricky trying tasks
Troubleshooting Tips and Tricks
47
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
One JNI Context Per Thread
Threading Options
49
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
JNI Context 2
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
OR
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
If all else fails Market filters
ndash Instruction set
ndash ARMv5ARMv7
ndash GL version
ndash Platform release
ndash Use Device Availability
Tips Standing Out from the Crowd
Start Small
ndash Download assets as-needed
ndash Hook me early instead of making me wait
Use Android backuprestore service (save to the cloud)
ndash Keep my progress when I switch devices
Support multiple control schemes
ndash Trackball D-pad virtual stick
ndash Let me decide what works best
Support install-to-SD
ndash Android Market users will knock your ratings if you donrsquot
51
Tips Standing Out from the Crowd
Profiling
ndash In-game profiling to select optimal settings per-device
Social
ndash Hook into social networks
ndash Use OpenID
Build a live wallpaper
ndash Own the userrsquos home screen with stats avatars
Analytics
ndash Market and in-game
In-app payments
ndash Consider alternative monetization techniques
52
Troubleshooting Development Tools
NVIDIA Debug Manager for Eclipse
ndash Simplifies setup for native debugger under Eclipse
bull developernvidiacomtegranvidia-debug-manager-android-ndk
WinGDB
ndash Use Visual Studio to debug Android NDK applications
bull wwwwingdbcom
vs-android
ndash Native MSBuild files for Android toolchain
bull vs-androidgooglecodecom
53
Troubleshooting Performance Tools
NVIDIA PerfHUD ES
ndash developernvidiacomtegraperfhud-es
Adreno Profiler
ndash developerqualcommcomshowcaseadreno-profiler
POWERVR Insider Utilities
ndash Including PVRTrace and PVRTune
ndash wwwimgteccompowervrinsiderpowervr-utilitiesasp
54
developerandroidcomsdkndkGoogleGameDevAndroid
Feedback httpgooglNudVs
QampA
55
Development Flow Makefiles
16
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Set up project
Write makefiles
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
$ampampampltPamp$(+)+-00+1234567QL6IER$ampampAgt++++++)+05BC0DE85$ampampampJ++++++++)+4B9C$ampamp$MJ++++++++++)+61B5+61B53NS
APP_STL = gnustl_static
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
$ampampampltPamp$(+)+-00+1234567QL6IER$ampampAgt++++++)+05BC0DE85$ampampampJ++++++++)+4B9C$ampamp$MJ++++++++++)+61B5+61B53NS
APP_STL = gnustl_static
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Interface Classes
Write interface in Java
ndash Use amp) keyword
17
LTC+I1K846I54KC0DE85U
QQ+H6LL6+VI6+8R5N+05B662
L9B05+0WW+GDPXJ5B+YR84W+$R5N5R2+Z
++WRR5+Z++++gt2WR1K0I45B662-[C0DE85[7U++
++Q]]+++]+^L61+_54R`+R`+9668R+N5_+_54R`+++]+^L61+`5C`R+R`+9668R+N5_+`5C`R+++]Q+++L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7U+++L9B05+WRR5+8R5N+NI54+WRL-7U
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
PXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]LPXJ8Na+EIBER+IBEa+E58R+a+E58R+B7+Z
++E0WW+0W++-]LPXJ8N73dGRBER0WW-LPXJ8Na+IBE7U
++E1R`I4J+54++-]LPXJ8N73dGRR`I4J-+++++++++++++++++++++++++++++LPXJ8Na+0Wa+[RTm2N8RW[a+[-n7=[7U
++-]LPXJ8N73d00=I54R`I4-LPXJ8Na+IBEa+54a+PXJltA7U
Development Flow Calling Dalvik Code Within CC++
20
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Build and Deploy
gt=0Alt-amp49BCDBEFG6HI
ndash Builds C libraries and emits so files
gt)-3
ndash (or ant release)
ndash Builds Java classes apk package
gtamp=44
ndash Deploys to emulator or device
21
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdbgdb-rsp over named pipe
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdb
EclipseVS
gdb-rsp over named pipe
gdb-MI
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Important Tip
B)-36amp3)$$)J23
Bringing Your Game to Android
24
Devices Accessing Android Market
25
Android 16
Android 15
Android 23
Android 233
Android 30
Two Week Period Published May 2011
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
NativeActivity is just starting
ndash 43 of checking-in devices can utilize it
ndash For non-tablet-specific titles we can take advantage of NativeActivity without becoming incompatible
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Platform-specific Resources
Using NativeActivity Compatibly
27
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dV0WcQBII0d++++cBII0+81[8IRG58C6B64[dR69cQBII0dcQ6WI96Wd
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dR69cQBII0d++++cBII0+81[8IRG58C6B64[dV0WcQBII0dcQ6WI96Wd
Using NativeActivity Compatibly
28
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
cR5N5R2+846I54)81[Kgt$XR5N$R5N5R2[+++846I54)8B04[^BII0QRWRG58C6B64[d++c1R34R+846I54)81[846I54KLLK05B81[+++++846I54)N09[W8R5N[+Qd++++++++++++++++++++++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6d++++++++++++cQR5N5R2dcR5N5R2+846I54)81[K1I$R5N5R2[+++846I54)8B04[^BII0Q8IRG58C6B64[d++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6dcQR5N5R2d
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+W8R5N$F$Ggt+)+3$XltJXm$gtltFJgt+ )+C09R50WK+k+ LL3846I5438R5NK$JMgt+)+30GgtND+3040+300IC+30G+30846I54$gt$JJMlt$ltJgt+ )+846I548R5NLLC09$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7-00+51LI6R31I490a846I54Q8R5NLLC097
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
LTC+I1KY1L0KW88C0WU
L9B05+0WW+gt$XR5N$R5N5R2+YR84W+846I54KLLKXR5N$R5N5R2+Z
++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
LTC+I1KY1L0KW88C0WU
L9B05+0WW+1I$R5N5R2+YR84W+846I54KLLK$R5N5R2+Z++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++++++gt2WR1K0I45B662-[WE85[7U++++KKK
Key Game Components
33
Lifecycle
Graphics Sound
Input
Assets
Activity LifecycleLifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Process LifecycleLifecycle
Android keeps application processes around for as long as possible
ndash Even when the activity is closed with V585W`-7 or the back key is pressed
The foreground activity process is considered the most important
ndash It can still be killed as a last resort
Visible activities are also given high priority
ndash Backgrounded activities are considered less important
ndash Processes with no active activities are killed first
Implications of the Process LifecycleLifecycle
Be careful with static initializers
ndash Your library cannot be unloaded while your process is active
bull Donrsquot assume that your static initializers will be run when your activity is created
Be careful with threads
ndash Threads are tied to the process not the activity
bull Your threads will continue to run at reduced priority even if your activity is backgrounded or destroyed
ndash Gameplay should stop during onPause
bull It might make sense to keep certain threads running - your activity may still be visible
ndash Make sure all native code is cleaned up during onDestroy
bull Users expect that your application will no longer be active when its activity is destroyed
The Basics
Key handling
ndash Your device most likely has capacitive buttons
bull Look for complete state transitions of I8m2I_8I8m2AL
bull Avoid overriding 45WLR`m2N8R
ndash Use I8m290R5L0I8m2I8Camp6WW
bull Keep your game behaving like an Android application
TouchMultitouch handling
ndash With I8I9`N8R
bull take advantage of built-in gesture processing
ndash use gt0GWR96RRI6 and GWR96RRI6
ndash Most devices now support multitouch
bull determine if your device can track distinct points
ndash `Wgt2WR1FR96-F$AltA(gtltXAJA(JgtJX)
37
Input
Other Input
Trackball handling
ndash With I86TB00N8R
bull Unhandled events turn into dpad events
Motion handling
ndash With I8gt8WI6`8C4
bull Must be registered with the gt8WI68C6
bull Disable unneeded sensors especially when paused
ndash Active sensors will quickly drain the battery
38
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
OpenGL
GLSurfaceView
ndash Creates the compatible context
bull Contexts are shared between native code and Dalvik
ndash Creates a rendering thread
ndash Releases the context during onPause
ndash Not the most efficient way to multitask withOpenGL but it avoids some driver issues
When context is lost
ndash Reload resources
bull Textures
bull Buffer objects
bull Shaders
ndash Names donrsquot persist
40
Graphics
Texture Formats
Android encourages innovation in hardware
ndash Chipset vendors use several kinds of proprietary texture compression formats
ndash OpenGL ES supports multiple compressed formats none mandatory
Solutions
ndash Uncompressed Textures
ndash Use ETC1 ndash broad support in 20
bull Optimized around photographic data
bull No Alpha
ndash Use Multi-APK (coming soon)
ndash Put textures on an asset server
bull Detect support at runtime
bull Download to each device
41
Graphics
Drawing for Performance
Draw order is important
ndash Has no impact on some platforms means everything on others
ndash Draw front to back to make best use of early rejects
Use VBOs
ndash Avoid unnecessary state changes
Textures
ndash Use power of 2 sized textures
bull It can be very slow
bull On some chipsets not all address modes work
42
Graphics
Writing Compatible Shaders
Query query
ndash Make sure to query for number of attributes varying and uniforms supported
bull Varies between devices
bull Not respecting will make your application crash
bull ldquoSupportedrdquo does not mean ldquoperforms wellrdquo
Conditions
ndash Avoid as much as possible
bull if necessary put them last in the shader
ndash Use mix() clamp() etc to create the same result
discard()
ndash Avoid discard()
bull if necessary it should be last
43
Graphics
Audio Solutions
Full track audio
s 45amp026
bull Plays multiple formats with codec support
bull Plays from filesystem or from network
bull Has high latency memory and CPU usage for quick sound effects
Sound effects and clips
s gtI984ampII0
bull Plays multiple formats with codec support
bull Preloads audio files to a pool
ndash Plays them with low latency
44
Sound
Audio Solutions
Application-generated audio
s $945I6T
bull Plays PCM audio only with minimal latency
bull Useful for applications that wish to perform sound processing or mixing
OpenSLES
ndash Combines capabilities of 45amp026 and $945I6T
ndash Available only in the NDK
ndash Requires Android 23 and higher
45
Sound
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
Use native AssetManager
ndash Gingerbread and Beyond
Targeting tricky trying tasks
Troubleshooting Tips and Tricks
47
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
One JNI Context Per Thread
Threading Options
49
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
JNI Context 2
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
OR
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
If all else fails Market filters
ndash Instruction set
ndash ARMv5ARMv7
ndash GL version
ndash Platform release
ndash Use Device Availability
Tips Standing Out from the Crowd
Start Small
ndash Download assets as-needed
ndash Hook me early instead of making me wait
Use Android backuprestore service (save to the cloud)
ndash Keep my progress when I switch devices
Support multiple control schemes
ndash Trackball D-pad virtual stick
ndash Let me decide what works best
Support install-to-SD
ndash Android Market users will knock your ratings if you donrsquot
51
Tips Standing Out from the Crowd
Profiling
ndash In-game profiling to select optimal settings per-device
Social
ndash Hook into social networks
ndash Use OpenID
Build a live wallpaper
ndash Own the userrsquos home screen with stats avatars
Analytics
ndash Market and in-game
In-app payments
ndash Consider alternative monetization techniques
52
Troubleshooting Development Tools
NVIDIA Debug Manager for Eclipse
ndash Simplifies setup for native debugger under Eclipse
bull developernvidiacomtegranvidia-debug-manager-android-ndk
WinGDB
ndash Use Visual Studio to debug Android NDK applications
bull wwwwingdbcom
vs-android
ndash Native MSBuild files for Android toolchain
bull vs-androidgooglecodecom
53
Troubleshooting Performance Tools
NVIDIA PerfHUD ES
ndash developernvidiacomtegraperfhud-es
Adreno Profiler
ndash developerqualcommcomshowcaseadreno-profiler
POWERVR Insider Utilities
ndash Including PVRTrace and PVRTune
ndash wwwimgteccompowervrinsiderpowervr-utilitiesasp
54
developerandroidcomsdkndkGoogleGameDevAndroid
Feedback httpgooglNudVs
QampA
55
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
$ampampampltPamp$(+)+-00+1234567QL6IER$ampampAgt++++++)+05BC0DE85$ampampampJ++++++++)+4B9C$ampamp$MJ++++++++++)+61B5+61B53NS
APP_STL = gnustl_static
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
$ampampampltPamp$(+)+-00+1234567QL6IER$ampampAgt++++++)+05BC0DE85$ampampampJ++++++++)+4B9C$ampamp$MJ++++++++++)+61B5+61B53NS
APP_STL = gnustl_static
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Interface Classes
Write interface in Java
ndash Use amp) keyword
17
LTC+I1K846I54KC0DE85U
QQ+H6LL6+VI6+8R5N+05B662
L9B05+0WW+GDPXJ5B+YR84W+$R5N5R2+Z
++WRR5+Z++++gt2WR1K0I45B662-[C0DE85[7U++
++Q]]+++]+^L61+_54R`+R`+9668R+N5_+_54R`+++]+^L61+`5C`R+R`+9668R+N5_+`5C`R+++]Q+++L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7U+++L9B05+WRR5+8R5N+NI54+WRL-7U
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
PXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]LPXJ8Na+EIBER+IBEa+E58R+a+E58R+B7+Z
++E0WW+0W++-]LPXJ8N73dGRBER0WW-LPXJ8Na+IBE7U
++E1R`I4J+54++-]LPXJ8N73dGRR`I4J-+++++++++++++++++++++++++++++LPXJ8Na+0Wa+[RTm2N8RW[a+[-n7=[7U
++-]LPXJ8N73d00=I54R`I4-LPXJ8Na+IBEa+54a+PXJltA7U
Development Flow Calling Dalvik Code Within CC++
20
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Build and Deploy
gt=0Alt-amp49BCDBEFG6HI
ndash Builds C libraries and emits so files
gt)-3
ndash (or ant release)
ndash Builds Java classes apk package
gtamp=44
ndash Deploys to emulator or device
21
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdbgdb-rsp over named pipe
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdb
EclipseVS
gdb-rsp over named pipe
gdb-MI
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Important Tip
B)-36amp3)$$)J23
Bringing Your Game to Android
24
Devices Accessing Android Market
25
Android 16
Android 15
Android 23
Android 233
Android 30
Two Week Period Published May 2011
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
NativeActivity is just starting
ndash 43 of checking-in devices can utilize it
ndash For non-tablet-specific titles we can take advantage of NativeActivity without becoming incompatible
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Platform-specific Resources
Using NativeActivity Compatibly
27
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dV0WcQBII0d++++cBII0+81[8IRG58C6B64[dR69cQBII0dcQ6WI96Wd
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dR69cQBII0d++++cBII0+81[8IRG58C6B64[dV0WcQBII0dcQ6WI96Wd
Using NativeActivity Compatibly
28
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
cR5N5R2+846I54)81[Kgt$XR5N$R5N5R2[+++846I54)8B04[^BII0QRWRG58C6B64[d++c1R34R+846I54)81[846I54KLLK05B81[+++++846I54)N09[W8R5N[+Qd++++++++++++++++++++++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6d++++++++++++cQR5N5R2dcR5N5R2+846I54)81[K1I$R5N5R2[+++846I54)8B04[^BII0Q8IRG58C6B64[d++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6dcQR5N5R2d
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+W8R5N$F$Ggt+)+3$XltJXm$gtltFJgt+ )+C09R50WK+k+ LL3846I5438R5NK$JMgt+)+30GgtND+3040+300IC+30G+30846I54$gt$JJMlt$ltJgt+ )+846I548R5NLLC09$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7-00+51LI6R31I490a846I54Q8R5NLLC097
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
LTC+I1KY1L0KW88C0WU
L9B05+0WW+gt$XR5N$R5N5R2+YR84W+846I54KLLKXR5N$R5N5R2+Z
++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
LTC+I1KY1L0KW88C0WU
L9B05+0WW+1I$R5N5R2+YR84W+846I54KLLK$R5N5R2+Z++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++++++gt2WR1K0I45B662-[WE85[7U++++KKK
Key Game Components
33
Lifecycle
Graphics Sound
Input
Assets
Activity LifecycleLifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Process LifecycleLifecycle
Android keeps application processes around for as long as possible
ndash Even when the activity is closed with V585W`-7 or the back key is pressed
The foreground activity process is considered the most important
ndash It can still be killed as a last resort
Visible activities are also given high priority
ndash Backgrounded activities are considered less important
ndash Processes with no active activities are killed first
Implications of the Process LifecycleLifecycle
Be careful with static initializers
ndash Your library cannot be unloaded while your process is active
bull Donrsquot assume that your static initializers will be run when your activity is created
Be careful with threads
ndash Threads are tied to the process not the activity
bull Your threads will continue to run at reduced priority even if your activity is backgrounded or destroyed
ndash Gameplay should stop during onPause
bull It might make sense to keep certain threads running - your activity may still be visible
ndash Make sure all native code is cleaned up during onDestroy
bull Users expect that your application will no longer be active when its activity is destroyed
The Basics
Key handling
ndash Your device most likely has capacitive buttons
bull Look for complete state transitions of I8m2I_8I8m2AL
bull Avoid overriding 45WLR`m2N8R
ndash Use I8m290R5L0I8m2I8Camp6WW
bull Keep your game behaving like an Android application
TouchMultitouch handling
ndash With I8I9`N8R
bull take advantage of built-in gesture processing
ndash use gt0GWR96RRI6 and GWR96RRI6
ndash Most devices now support multitouch
bull determine if your device can track distinct points
ndash `Wgt2WR1FR96-F$AltA(gtltXAJA(JgtJX)
37
Input
Other Input
Trackball handling
ndash With I86TB00N8R
bull Unhandled events turn into dpad events
Motion handling
ndash With I8gt8WI6`8C4
bull Must be registered with the gt8WI68C6
bull Disable unneeded sensors especially when paused
ndash Active sensors will quickly drain the battery
38
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
OpenGL
GLSurfaceView
ndash Creates the compatible context
bull Contexts are shared between native code and Dalvik
ndash Creates a rendering thread
ndash Releases the context during onPause
ndash Not the most efficient way to multitask withOpenGL but it avoids some driver issues
When context is lost
ndash Reload resources
bull Textures
bull Buffer objects
bull Shaders
ndash Names donrsquot persist
40
Graphics
Texture Formats
Android encourages innovation in hardware
ndash Chipset vendors use several kinds of proprietary texture compression formats
ndash OpenGL ES supports multiple compressed formats none mandatory
Solutions
ndash Uncompressed Textures
ndash Use ETC1 ndash broad support in 20
bull Optimized around photographic data
bull No Alpha
ndash Use Multi-APK (coming soon)
ndash Put textures on an asset server
bull Detect support at runtime
bull Download to each device
41
Graphics
Drawing for Performance
Draw order is important
ndash Has no impact on some platforms means everything on others
ndash Draw front to back to make best use of early rejects
Use VBOs
ndash Avoid unnecessary state changes
Textures
ndash Use power of 2 sized textures
bull It can be very slow
bull On some chipsets not all address modes work
42
Graphics
Writing Compatible Shaders
Query query
ndash Make sure to query for number of attributes varying and uniforms supported
bull Varies between devices
bull Not respecting will make your application crash
bull ldquoSupportedrdquo does not mean ldquoperforms wellrdquo
Conditions
ndash Avoid as much as possible
bull if necessary put them last in the shader
ndash Use mix() clamp() etc to create the same result
discard()
ndash Avoid discard()
bull if necessary it should be last
43
Graphics
Audio Solutions
Full track audio
s 45amp026
bull Plays multiple formats with codec support
bull Plays from filesystem or from network
bull Has high latency memory and CPU usage for quick sound effects
Sound effects and clips
s gtI984ampII0
bull Plays multiple formats with codec support
bull Preloads audio files to a pool
ndash Plays them with low latency
44
Sound
Audio Solutions
Application-generated audio
s $945I6T
bull Plays PCM audio only with minimal latency
bull Useful for applications that wish to perform sound processing or mixing
OpenSLES
ndash Combines capabilities of 45amp026 and $945I6T
ndash Available only in the NDK
ndash Requires Android 23 and higher
45
Sound
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
Use native AssetManager
ndash Gingerbread and Beyond
Targeting tricky trying tasks
Troubleshooting Tips and Tricks
47
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
One JNI Context Per Thread
Threading Options
49
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
JNI Context 2
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
OR
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
If all else fails Market filters
ndash Instruction set
ndash ARMv5ARMv7
ndash GL version
ndash Platform release
ndash Use Device Availability
Tips Standing Out from the Crowd
Start Small
ndash Download assets as-needed
ndash Hook me early instead of making me wait
Use Android backuprestore service (save to the cloud)
ndash Keep my progress when I switch devices
Support multiple control schemes
ndash Trackball D-pad virtual stick
ndash Let me decide what works best
Support install-to-SD
ndash Android Market users will knock your ratings if you donrsquot
51
Tips Standing Out from the Crowd
Profiling
ndash In-game profiling to select optimal settings per-device
Social
ndash Hook into social networks
ndash Use OpenID
Build a live wallpaper
ndash Own the userrsquos home screen with stats avatars
Analytics
ndash Market and in-game
In-app payments
ndash Consider alternative monetization techniques
52
Troubleshooting Development Tools
NVIDIA Debug Manager for Eclipse
ndash Simplifies setup for native debugger under Eclipse
bull developernvidiacomtegranvidia-debug-manager-android-ndk
WinGDB
ndash Use Visual Studio to debug Android NDK applications
bull wwwwingdbcom
vs-android
ndash Native MSBuild files for Android toolchain
bull vs-androidgooglecodecom
53
Troubleshooting Performance Tools
NVIDIA PerfHUD ES
ndash developernvidiacomtegraperfhud-es
Adreno Profiler
ndash developerqualcommcomshowcaseadreno-profiler
POWERVR Insider Utilities
ndash Including PVRTrace and PVRTune
ndash wwwimgteccompowervrinsiderpowervr-utilitiesasp
54
developerandroidcomsdkndkGoogleGameDevAndroid
Feedback httpgooglNudVs
QampA
55
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
$ampampampltPamp$(+)+-00+1234567QL6IER$ampampAgt++++++)+05BC0DE85$ampampampJ++++++++)+4B9C$ampamp$MJ++++++++++)+61B5+61B53NS
APP_STL = gnustl_static
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
$ampampampltPamp$(+)+-00+1234567QL6IER$ampampAgt++++++)+05BC0DE85$ampampampJ++++++++)+4B9C$ampamp$MJ++++++++++)+61B5+61B53NS
APP_STL = gnustl_static
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Interface Classes
Write interface in Java
ndash Use amp) keyword
17
LTC+I1K846I54KC0DE85U
QQ+H6LL6+VI6+8R5N+05B662
L9B05+0WW+GDPXJ5B+YR84W+$R5N5R2+Z
++WRR5+Z++++gt2WR1K0I45B662-[C0DE85[7U++
++Q]]+++]+^L61+_54R`+R`+9668R+N5_+_54R`+++]+^L61+`5C`R+R`+9668R+N5_+`5C`R+++]Q+++L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7U+++L9B05+WRR5+8R5N+NI54+WRL-7U
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
PXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]LPXJ8Na+EIBER+IBEa+E58R+a+E58R+B7+Z
++E0WW+0W++-]LPXJ8N73dGRBER0WW-LPXJ8Na+IBE7U
++E1R`I4J+54++-]LPXJ8N73dGRR`I4J-+++++++++++++++++++++++++++++LPXJ8Na+0Wa+[RTm2N8RW[a+[-n7=[7U
++-]LPXJ8N73d00=I54R`I4-LPXJ8Na+IBEa+54a+PXJltA7U
Development Flow Calling Dalvik Code Within CC++
20
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Build and Deploy
gt=0Alt-amp49BCDBEFG6HI
ndash Builds C libraries and emits so files
gt)-3
ndash (or ant release)
ndash Builds Java classes apk package
gtamp=44
ndash Deploys to emulator or device
21
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdbgdb-rsp over named pipe
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdb
EclipseVS
gdb-rsp over named pipe
gdb-MI
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Important Tip
B)-36amp3)$$)J23
Bringing Your Game to Android
24
Devices Accessing Android Market
25
Android 16
Android 15
Android 23
Android 233
Android 30
Two Week Period Published May 2011
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
NativeActivity is just starting
ndash 43 of checking-in devices can utilize it
ndash For non-tablet-specific titles we can take advantage of NativeActivity without becoming incompatible
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Platform-specific Resources
Using NativeActivity Compatibly
27
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dV0WcQBII0d++++cBII0+81[8IRG58C6B64[dR69cQBII0dcQ6WI96Wd
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dR69cQBII0d++++cBII0+81[8IRG58C6B64[dV0WcQBII0dcQ6WI96Wd
Using NativeActivity Compatibly
28
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
cR5N5R2+846I54)81[Kgt$XR5N$R5N5R2[+++846I54)8B04[^BII0QRWRG58C6B64[d++c1R34R+846I54)81[846I54KLLK05B81[+++++846I54)N09[W8R5N[+Qd++++++++++++++++++++++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6d++++++++++++cQR5N5R2dcR5N5R2+846I54)81[K1I$R5N5R2[+++846I54)8B04[^BII0Q8IRG58C6B64[d++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6dcQR5N5R2d
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+W8R5N$F$Ggt+)+3$XltJXm$gtltFJgt+ )+C09R50WK+k+ LL3846I5438R5NK$JMgt+)+30GgtND+3040+300IC+30G+30846I54$gt$JJMlt$ltJgt+ )+846I548R5NLLC09$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7-00+51LI6R31I490a846I54Q8R5NLLC097
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
LTC+I1KY1L0KW88C0WU
L9B05+0WW+gt$XR5N$R5N5R2+YR84W+846I54KLLKXR5N$R5N5R2+Z
++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
LTC+I1KY1L0KW88C0WU
L9B05+0WW+1I$R5N5R2+YR84W+846I54KLLK$R5N5R2+Z++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++++++gt2WR1K0I45B662-[WE85[7U++++KKK
Key Game Components
33
Lifecycle
Graphics Sound
Input
Assets
Activity LifecycleLifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Process LifecycleLifecycle
Android keeps application processes around for as long as possible
ndash Even when the activity is closed with V585W`-7 or the back key is pressed
The foreground activity process is considered the most important
ndash It can still be killed as a last resort
Visible activities are also given high priority
ndash Backgrounded activities are considered less important
ndash Processes with no active activities are killed first
Implications of the Process LifecycleLifecycle
Be careful with static initializers
ndash Your library cannot be unloaded while your process is active
bull Donrsquot assume that your static initializers will be run when your activity is created
Be careful with threads
ndash Threads are tied to the process not the activity
bull Your threads will continue to run at reduced priority even if your activity is backgrounded or destroyed
ndash Gameplay should stop during onPause
bull It might make sense to keep certain threads running - your activity may still be visible
ndash Make sure all native code is cleaned up during onDestroy
bull Users expect that your application will no longer be active when its activity is destroyed
The Basics
Key handling
ndash Your device most likely has capacitive buttons
bull Look for complete state transitions of I8m2I_8I8m2AL
bull Avoid overriding 45WLR`m2N8R
ndash Use I8m290R5L0I8m2I8Camp6WW
bull Keep your game behaving like an Android application
TouchMultitouch handling
ndash With I8I9`N8R
bull take advantage of built-in gesture processing
ndash use gt0GWR96RRI6 and GWR96RRI6
ndash Most devices now support multitouch
bull determine if your device can track distinct points
ndash `Wgt2WR1FR96-F$AltA(gtltXAJA(JgtJX)
37
Input
Other Input
Trackball handling
ndash With I86TB00N8R
bull Unhandled events turn into dpad events
Motion handling
ndash With I8gt8WI6`8C4
bull Must be registered with the gt8WI68C6
bull Disable unneeded sensors especially when paused
ndash Active sensors will quickly drain the battery
38
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
OpenGL
GLSurfaceView
ndash Creates the compatible context
bull Contexts are shared between native code and Dalvik
ndash Creates a rendering thread
ndash Releases the context during onPause
ndash Not the most efficient way to multitask withOpenGL but it avoids some driver issues
When context is lost
ndash Reload resources
bull Textures
bull Buffer objects
bull Shaders
ndash Names donrsquot persist
40
Graphics
Texture Formats
Android encourages innovation in hardware
ndash Chipset vendors use several kinds of proprietary texture compression formats
ndash OpenGL ES supports multiple compressed formats none mandatory
Solutions
ndash Uncompressed Textures
ndash Use ETC1 ndash broad support in 20
bull Optimized around photographic data
bull No Alpha
ndash Use Multi-APK (coming soon)
ndash Put textures on an asset server
bull Detect support at runtime
bull Download to each device
41
Graphics
Drawing for Performance
Draw order is important
ndash Has no impact on some platforms means everything on others
ndash Draw front to back to make best use of early rejects
Use VBOs
ndash Avoid unnecessary state changes
Textures
ndash Use power of 2 sized textures
bull It can be very slow
bull On some chipsets not all address modes work
42
Graphics
Writing Compatible Shaders
Query query
ndash Make sure to query for number of attributes varying and uniforms supported
bull Varies between devices
bull Not respecting will make your application crash
bull ldquoSupportedrdquo does not mean ldquoperforms wellrdquo
Conditions
ndash Avoid as much as possible
bull if necessary put them last in the shader
ndash Use mix() clamp() etc to create the same result
discard()
ndash Avoid discard()
bull if necessary it should be last
43
Graphics
Audio Solutions
Full track audio
s 45amp026
bull Plays multiple formats with codec support
bull Plays from filesystem or from network
bull Has high latency memory and CPU usage for quick sound effects
Sound effects and clips
s gtI984ampII0
bull Plays multiple formats with codec support
bull Preloads audio files to a pool
ndash Plays them with low latency
44
Sound
Audio Solutions
Application-generated audio
s $945I6T
bull Plays PCM audio only with minimal latency
bull Useful for applications that wish to perform sound processing or mixing
OpenSLES
ndash Combines capabilities of 45amp026 and $945I6T
ndash Available only in the NDK
ndash Requires Android 23 and higher
45
Sound
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
Use native AssetManager
ndash Gingerbread and Beyond
Targeting tricky trying tasks
Troubleshooting Tips and Tricks
47
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
One JNI Context Per Thread
Threading Options
49
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
JNI Context 2
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
OR
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
If all else fails Market filters
ndash Instruction set
ndash ARMv5ARMv7
ndash GL version
ndash Platform release
ndash Use Device Availability
Tips Standing Out from the Crowd
Start Small
ndash Download assets as-needed
ndash Hook me early instead of making me wait
Use Android backuprestore service (save to the cloud)
ndash Keep my progress when I switch devices
Support multiple control schemes
ndash Trackball D-pad virtual stick
ndash Let me decide what works best
Support install-to-SD
ndash Android Market users will knock your ratings if you donrsquot
51
Tips Standing Out from the Crowd
Profiling
ndash In-game profiling to select optimal settings per-device
Social
ndash Hook into social networks
ndash Use OpenID
Build a live wallpaper
ndash Own the userrsquos home screen with stats avatars
Analytics
ndash Market and in-game
In-app payments
ndash Consider alternative monetization techniques
52
Troubleshooting Development Tools
NVIDIA Debug Manager for Eclipse
ndash Simplifies setup for native debugger under Eclipse
bull developernvidiacomtegranvidia-debug-manager-android-ndk
WinGDB
ndash Use Visual Studio to debug Android NDK applications
bull wwwwingdbcom
vs-android
ndash Native MSBuild files for Android toolchain
bull vs-androidgooglecodecom
53
Troubleshooting Performance Tools
NVIDIA PerfHUD ES
ndash developernvidiacomtegraperfhud-es
Adreno Profiler
ndash developerqualcommcomshowcaseadreno-profiler
POWERVR Insider Utilities
ndash Including PVRTrace and PVRTune
ndash wwwimgteccompowervrinsiderpowervr-utilitiesasp
54
developerandroidcomsdkndkGoogleGameDevAndroid
Feedback httpgooglNudVs
QampA
55
Development Flow Makefiles
16
$amp$()+-00+1234567
58094+-$lt=$ltgt7
$A++++)+05BC0DE85$F$Ggt++++)+3H66I6$gtltFJgt+)+C0I4KLL$JMgt++++)+300IC+30GgtND
58094+-MAJgt($ltJMlt$ltO7
$ampampampltPamp$(+)+-00+1234567QL6IER$ampampAgt++++++)+05BC0DE85$ampampampJ++++++++)+4B9C$ampamp$MJ++++++++++)+61B5+61B53NS
APP_STL = gnustl_static
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Interface Classes
Write interface in Java
ndash Use amp) keyword
17
LTC+I1K846I54KC0DE85U
QQ+H6LL6+VI6+8R5N+05B662
L9B05+0WW+GDPXJ5B+YR84W+$R5N5R2+Z
++WRR5+Z++++gt2WR1K0I45B662-[C0DE85[7U++
++Q]]+++]+^L61+_54R`+R`+9668R+N5_+_54R`+++]+^L61+`5C`R+R`+9668R+N5_+`5C`R+++]Q+++L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7U+++L9B05+WRR5+8R5N+NI54+WRL-7U
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
PXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]LPXJ8Na+EIBER+IBEa+E58R+a+E58R+B7+Z
++E0WW+0W++-]LPXJ8N73dGRBER0WW-LPXJ8Na+IBE7U
++E1R`I4J+54++-]LPXJ8N73dGRR`I4J-+++++++++++++++++++++++++++++LPXJ8Na+0Wa+[RTm2N8RW[a+[-n7=[7U
++-]LPXJ8N73d00=I54R`I4-LPXJ8Na+IBEa+54a+PXJltA7U
Development Flow Calling Dalvik Code Within CC++
20
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Build and Deploy
gt=0Alt-amp49BCDBEFG6HI
ndash Builds C libraries and emits so files
gt)-3
ndash (or ant release)
ndash Builds Java classes apk package
gtamp=44
ndash Deploys to emulator or device
21
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdbgdb-rsp over named pipe
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdb
EclipseVS
gdb-rsp over named pipe
gdb-MI
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Important Tip
B)-36amp3)$$)J23
Bringing Your Game to Android
24
Devices Accessing Android Market
25
Android 16
Android 15
Android 23
Android 233
Android 30
Two Week Period Published May 2011
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
NativeActivity is just starting
ndash 43 of checking-in devices can utilize it
ndash For non-tablet-specific titles we can take advantage of NativeActivity without becoming incompatible
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Platform-specific Resources
Using NativeActivity Compatibly
27
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dV0WcQBII0d++++cBII0+81[8IRG58C6B64[dR69cQBII0dcQ6WI96Wd
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dR69cQBII0d++++cBII0+81[8IRG58C6B64[dV0WcQBII0dcQ6WI96Wd
Using NativeActivity Compatibly
28
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
cR5N5R2+846I54)81[Kgt$XR5N$R5N5R2[+++846I54)8B04[^BII0QRWRG58C6B64[d++c1R34R+846I54)81[846I54KLLK05B81[+++++846I54)N09[W8R5N[+Qd++++++++++++++++++++++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6d++++++++++++cQR5N5R2dcR5N5R2+846I54)81[K1I$R5N5R2[+++846I54)8B04[^BII0Q8IRG58C6B64[d++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6dcQR5N5R2d
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+W8R5N$F$Ggt+)+3$XltJXm$gtltFJgt+ )+C09R50WK+k+ LL3846I5438R5NK$JMgt+)+30GgtND+3040+300IC+30G+30846I54$gt$JJMlt$ltJgt+ )+846I548R5NLLC09$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7-00+51LI6R31I490a846I54Q8R5NLLC097
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
LTC+I1KY1L0KW88C0WU
L9B05+0WW+gt$XR5N$R5N5R2+YR84W+846I54KLLKXR5N$R5N5R2+Z
++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
LTC+I1KY1L0KW88C0WU
L9B05+0WW+1I$R5N5R2+YR84W+846I54KLLK$R5N5R2+Z++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++++++gt2WR1K0I45B662-[WE85[7U++++KKK
Key Game Components
33
Lifecycle
Graphics Sound
Input
Assets
Activity LifecycleLifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Process LifecycleLifecycle
Android keeps application processes around for as long as possible
ndash Even when the activity is closed with V585W`-7 or the back key is pressed
The foreground activity process is considered the most important
ndash It can still be killed as a last resort
Visible activities are also given high priority
ndash Backgrounded activities are considered less important
ndash Processes with no active activities are killed first
Implications of the Process LifecycleLifecycle
Be careful with static initializers
ndash Your library cannot be unloaded while your process is active
bull Donrsquot assume that your static initializers will be run when your activity is created
Be careful with threads
ndash Threads are tied to the process not the activity
bull Your threads will continue to run at reduced priority even if your activity is backgrounded or destroyed
ndash Gameplay should stop during onPause
bull It might make sense to keep certain threads running - your activity may still be visible
ndash Make sure all native code is cleaned up during onDestroy
bull Users expect that your application will no longer be active when its activity is destroyed
The Basics
Key handling
ndash Your device most likely has capacitive buttons
bull Look for complete state transitions of I8m2I_8I8m2AL
bull Avoid overriding 45WLR`m2N8R
ndash Use I8m290R5L0I8m2I8Camp6WW
bull Keep your game behaving like an Android application
TouchMultitouch handling
ndash With I8I9`N8R
bull take advantage of built-in gesture processing
ndash use gt0GWR96RRI6 and GWR96RRI6
ndash Most devices now support multitouch
bull determine if your device can track distinct points
ndash `Wgt2WR1FR96-F$AltA(gtltXAJA(JgtJX)
37
Input
Other Input
Trackball handling
ndash With I86TB00N8R
bull Unhandled events turn into dpad events
Motion handling
ndash With I8gt8WI6`8C4
bull Must be registered with the gt8WI68C6
bull Disable unneeded sensors especially when paused
ndash Active sensors will quickly drain the battery
38
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
OpenGL
GLSurfaceView
ndash Creates the compatible context
bull Contexts are shared between native code and Dalvik
ndash Creates a rendering thread
ndash Releases the context during onPause
ndash Not the most efficient way to multitask withOpenGL but it avoids some driver issues
When context is lost
ndash Reload resources
bull Textures
bull Buffer objects
bull Shaders
ndash Names donrsquot persist
40
Graphics
Texture Formats
Android encourages innovation in hardware
ndash Chipset vendors use several kinds of proprietary texture compression formats
ndash OpenGL ES supports multiple compressed formats none mandatory
Solutions
ndash Uncompressed Textures
ndash Use ETC1 ndash broad support in 20
bull Optimized around photographic data
bull No Alpha
ndash Use Multi-APK (coming soon)
ndash Put textures on an asset server
bull Detect support at runtime
bull Download to each device
41
Graphics
Drawing for Performance
Draw order is important
ndash Has no impact on some platforms means everything on others
ndash Draw front to back to make best use of early rejects
Use VBOs
ndash Avoid unnecessary state changes
Textures
ndash Use power of 2 sized textures
bull It can be very slow
bull On some chipsets not all address modes work
42
Graphics
Writing Compatible Shaders
Query query
ndash Make sure to query for number of attributes varying and uniforms supported
bull Varies between devices
bull Not respecting will make your application crash
bull ldquoSupportedrdquo does not mean ldquoperforms wellrdquo
Conditions
ndash Avoid as much as possible
bull if necessary put them last in the shader
ndash Use mix() clamp() etc to create the same result
discard()
ndash Avoid discard()
bull if necessary it should be last
43
Graphics
Audio Solutions
Full track audio
s 45amp026
bull Plays multiple formats with codec support
bull Plays from filesystem or from network
bull Has high latency memory and CPU usage for quick sound effects
Sound effects and clips
s gtI984ampII0
bull Plays multiple formats with codec support
bull Preloads audio files to a pool
ndash Plays them with low latency
44
Sound
Audio Solutions
Application-generated audio
s $945I6T
bull Plays PCM audio only with minimal latency
bull Useful for applications that wish to perform sound processing or mixing
OpenSLES
ndash Combines capabilities of 45amp026 and $945I6T
ndash Available only in the NDK
ndash Requires Android 23 and higher
45
Sound
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
Use native AssetManager
ndash Gingerbread and Beyond
Targeting tricky trying tasks
Troubleshooting Tips and Tricks
47
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
One JNI Context Per Thread
Threading Options
49
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
JNI Context 2
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
OR
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
If all else fails Market filters
ndash Instruction set
ndash ARMv5ARMv7
ndash GL version
ndash Platform release
ndash Use Device Availability
Tips Standing Out from the Crowd
Start Small
ndash Download assets as-needed
ndash Hook me early instead of making me wait
Use Android backuprestore service (save to the cloud)
ndash Keep my progress when I switch devices
Support multiple control schemes
ndash Trackball D-pad virtual stick
ndash Let me decide what works best
Support install-to-SD
ndash Android Market users will knock your ratings if you donrsquot
51
Tips Standing Out from the Crowd
Profiling
ndash In-game profiling to select optimal settings per-device
Social
ndash Hook into social networks
ndash Use OpenID
Build a live wallpaper
ndash Own the userrsquos home screen with stats avatars
Analytics
ndash Market and in-game
In-app payments
ndash Consider alternative monetization techniques
52
Troubleshooting Development Tools
NVIDIA Debug Manager for Eclipse
ndash Simplifies setup for native debugger under Eclipse
bull developernvidiacomtegranvidia-debug-manager-android-ndk
WinGDB
ndash Use Visual Studio to debug Android NDK applications
bull wwwwingdbcom
vs-android
ndash Native MSBuild files for Android toolchain
bull vs-androidgooglecodecom
53
Troubleshooting Performance Tools
NVIDIA PerfHUD ES
ndash developernvidiacomtegraperfhud-es
Adreno Profiler
ndash developerqualcommcomshowcaseadreno-profiler
POWERVR Insider Utilities
ndash Including PVRTrace and PVRTune
ndash wwwimgteccompowervrinsiderpowervr-utilitiesasp
54
developerandroidcomsdkndkGoogleGameDevAndroid
Feedback httpgooglNudVs
QampA
55
Development Flow Interface Classes
Write interface in Java
ndash Use amp) keyword
17
LTC+I1K846I54KC0DE85U
QQ+H6LL6+VI6+8R5N+05B662
L9B05+0WW+GDPXJ5B+YR84W+$R5N5R2+Z
++WRR5+Z++++gt2WR1K0I45B662-[C0DE85[7U++
++Q]]+++]+^L61+_54R`+R`+9668R+N5_+_54R`+++]+^L61+`5C`R+R`+9668R+N5_+`5C`R+++]Q+++L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7U+++L9B05+WRR5+8R5N+NI54+WRL-7U
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
PXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]LPXJ8Na+EIBER+IBEa+E58R+a+E58R+B7+Z
++E0WW+0W++-]LPXJ8N73dGRBER0WW-LPXJ8Na+IBE7U
++E1R`I4J+54++-]LPXJ8N73dGRR`I4J-+++++++++++++++++++++++++++++LPXJ8Na+0Wa+[RTm2N8RW[a+[-n7=[7U
++-]LPXJ8N73d00=I54R`I4-LPXJ8Na+IBEa+54a+PXJltA7U
Development Flow Calling Dalvik Code Within CC++
20
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Build and Deploy
gt=0Alt-amp49BCDBEFG6HI
ndash Builds C libraries and emits so files
gt)-3
ndash (or ant release)
ndash Builds Java classes apk package
gtamp=44
ndash Deploys to emulator or device
21
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdbgdb-rsp over named pipe
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdb
EclipseVS
gdb-rsp over named pipe
gdb-MI
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Important Tip
B)-36amp3)$$)J23
Bringing Your Game to Android
24
Devices Accessing Android Market
25
Android 16
Android 15
Android 23
Android 233
Android 30
Two Week Period Published May 2011
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
NativeActivity is just starting
ndash 43 of checking-in devices can utilize it
ndash For non-tablet-specific titles we can take advantage of NativeActivity without becoming incompatible
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Platform-specific Resources
Using NativeActivity Compatibly
27
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dV0WcQBII0d++++cBII0+81[8IRG58C6B64[dR69cQBII0dcQ6WI96Wd
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dR69cQBII0d++++cBII0+81[8IRG58C6B64[dV0WcQBII0dcQ6WI96Wd
Using NativeActivity Compatibly
28
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
cR5N5R2+846I54)81[Kgt$XR5N$R5N5R2[+++846I54)8B04[^BII0QRWRG58C6B64[d++c1R34R+846I54)81[846I54KLLK05B81[+++++846I54)N09[W8R5N[+Qd++++++++++++++++++++++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6d++++++++++++cQR5N5R2dcR5N5R2+846I54)81[K1I$R5N5R2[+++846I54)8B04[^BII0Q8IRG58C6B64[d++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6dcQR5N5R2d
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+W8R5N$F$Ggt+)+3$XltJXm$gtltFJgt+ )+C09R50WK+k+ LL3846I5438R5NK$JMgt+)+30GgtND+3040+300IC+30G+30846I54$gt$JJMlt$ltJgt+ )+846I548R5NLLC09$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7-00+51LI6R31I490a846I54Q8R5NLLC097
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
LTC+I1KY1L0KW88C0WU
L9B05+0WW+gt$XR5N$R5N5R2+YR84W+846I54KLLKXR5N$R5N5R2+Z
++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
LTC+I1KY1L0KW88C0WU
L9B05+0WW+1I$R5N5R2+YR84W+846I54KLLK$R5N5R2+Z++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++++++gt2WR1K0I45B662-[WE85[7U++++KKK
Key Game Components
33
Lifecycle
Graphics Sound
Input
Assets
Activity LifecycleLifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Process LifecycleLifecycle
Android keeps application processes around for as long as possible
ndash Even when the activity is closed with V585W`-7 or the back key is pressed
The foreground activity process is considered the most important
ndash It can still be killed as a last resort
Visible activities are also given high priority
ndash Backgrounded activities are considered less important
ndash Processes with no active activities are killed first
Implications of the Process LifecycleLifecycle
Be careful with static initializers
ndash Your library cannot be unloaded while your process is active
bull Donrsquot assume that your static initializers will be run when your activity is created
Be careful with threads
ndash Threads are tied to the process not the activity
bull Your threads will continue to run at reduced priority even if your activity is backgrounded or destroyed
ndash Gameplay should stop during onPause
bull It might make sense to keep certain threads running - your activity may still be visible
ndash Make sure all native code is cleaned up during onDestroy
bull Users expect that your application will no longer be active when its activity is destroyed
The Basics
Key handling
ndash Your device most likely has capacitive buttons
bull Look for complete state transitions of I8m2I_8I8m2AL
bull Avoid overriding 45WLR`m2N8R
ndash Use I8m290R5L0I8m2I8Camp6WW
bull Keep your game behaving like an Android application
TouchMultitouch handling
ndash With I8I9`N8R
bull take advantage of built-in gesture processing
ndash use gt0GWR96RRI6 and GWR96RRI6
ndash Most devices now support multitouch
bull determine if your device can track distinct points
ndash `Wgt2WR1FR96-F$AltA(gtltXAJA(JgtJX)
37
Input
Other Input
Trackball handling
ndash With I86TB00N8R
bull Unhandled events turn into dpad events
Motion handling
ndash With I8gt8WI6`8C4
bull Must be registered with the gt8WI68C6
bull Disable unneeded sensors especially when paused
ndash Active sensors will quickly drain the battery
38
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
OpenGL
GLSurfaceView
ndash Creates the compatible context
bull Contexts are shared between native code and Dalvik
ndash Creates a rendering thread
ndash Releases the context during onPause
ndash Not the most efficient way to multitask withOpenGL but it avoids some driver issues
When context is lost
ndash Reload resources
bull Textures
bull Buffer objects
bull Shaders
ndash Names donrsquot persist
40
Graphics
Texture Formats
Android encourages innovation in hardware
ndash Chipset vendors use several kinds of proprietary texture compression formats
ndash OpenGL ES supports multiple compressed formats none mandatory
Solutions
ndash Uncompressed Textures
ndash Use ETC1 ndash broad support in 20
bull Optimized around photographic data
bull No Alpha
ndash Use Multi-APK (coming soon)
ndash Put textures on an asset server
bull Detect support at runtime
bull Download to each device
41
Graphics
Drawing for Performance
Draw order is important
ndash Has no impact on some platforms means everything on others
ndash Draw front to back to make best use of early rejects
Use VBOs
ndash Avoid unnecessary state changes
Textures
ndash Use power of 2 sized textures
bull It can be very slow
bull On some chipsets not all address modes work
42
Graphics
Writing Compatible Shaders
Query query
ndash Make sure to query for number of attributes varying and uniforms supported
bull Varies between devices
bull Not respecting will make your application crash
bull ldquoSupportedrdquo does not mean ldquoperforms wellrdquo
Conditions
ndash Avoid as much as possible
bull if necessary put them last in the shader
ndash Use mix() clamp() etc to create the same result
discard()
ndash Avoid discard()
bull if necessary it should be last
43
Graphics
Audio Solutions
Full track audio
s 45amp026
bull Plays multiple formats with codec support
bull Plays from filesystem or from network
bull Has high latency memory and CPU usage for quick sound effects
Sound effects and clips
s gtI984ampII0
bull Plays multiple formats with codec support
bull Preloads audio files to a pool
ndash Plays them with low latency
44
Sound
Audio Solutions
Application-generated audio
s $945I6T
bull Plays PCM audio only with minimal latency
bull Useful for applications that wish to perform sound processing or mixing
OpenSLES
ndash Combines capabilities of 45amp026 and $945I6T
ndash Available only in the NDK
ndash Requires Android 23 and higher
45
Sound
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
Use native AssetManager
ndash Gingerbread and Beyond
Targeting tricky trying tasks
Troubleshooting Tips and Tricks
47
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
One JNI Context Per Thread
Threading Options
49
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
JNI Context 2
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
OR
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
If all else fails Market filters
ndash Instruction set
ndash ARMv5ARMv7
ndash GL version
ndash Platform release
ndash Use Device Availability
Tips Standing Out from the Crowd
Start Small
ndash Download assets as-needed
ndash Hook me early instead of making me wait
Use Android backuprestore service (save to the cloud)
ndash Keep my progress when I switch devices
Support multiple control schemes
ndash Trackball D-pad virtual stick
ndash Let me decide what works best
Support install-to-SD
ndash Android Market users will knock your ratings if you donrsquot
51
Tips Standing Out from the Crowd
Profiling
ndash In-game profiling to select optimal settings per-device
Social
ndash Hook into social networks
ndash Use OpenID
Build a live wallpaper
ndash Own the userrsquos home screen with stats avatars
Analytics
ndash Market and in-game
In-app payments
ndash Consider alternative monetization techniques
52
Troubleshooting Development Tools
NVIDIA Debug Manager for Eclipse
ndash Simplifies setup for native debugger under Eclipse
bull developernvidiacomtegranvidia-debug-manager-android-ndk
WinGDB
ndash Use Visual Studio to debug Android NDK applications
bull wwwwingdbcom
vs-android
ndash Native MSBuild files for Android toolchain
bull vs-androidgooglecodecom
53
Troubleshooting Performance Tools
NVIDIA PerfHUD ES
ndash developernvidiacomtegraperfhud-es
Adreno Profiler
ndash developerqualcommcomshowcaseadreno-profiler
POWERVR Insider Utilities
ndash Including PVRTrace and PVRTune
ndash wwwimgteccompowervrinsiderpowervr-utilitiesasp
54
developerandroidcomsdkndkGoogleGameDevAndroid
Feedback httpgooglNudVs
QampA
55
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
PXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]LPXJ8Na+EIBER+IBEa+E58R+a+E58R+B7+Z
++E0WW+0W++-]LPXJ8N73dGRBER0WW-LPXJ8Na+IBE7U
++E1R`I4J+54++-]LPXJ8N73dGRR`I4J-+++++++++++++++++++++++++++++LPXJ8Na+0Wa+[RTm2N8RW[a+[-n7=[7U
++-]LPXJ8N73d00=I54R`I4-LPXJ8Na+IBEa+54a+PXJltA7U
Development Flow Calling Dalvik Code Within CC++
20
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Build and Deploy
gt=0Alt-amp49BCDBEFG6HI
ndash Builds C libraries and emits so files
gt)-3
ndash (or ant release)
ndash Builds Java classes apk package
gtamp=44
ndash Deploys to emulator or device
21
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdbgdb-rsp over named pipe
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdb
EclipseVS
gdb-rsp over named pipe
gdb-MI
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Important Tip
B)-36amp3)$$)J23
Bringing Your Game to Android
24
Devices Accessing Android Market
25
Android 16
Android 15
Android 23
Android 233
Android 30
Two Week Period Published May 2011
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
NativeActivity is just starting
ndash 43 of checking-in devices can utilize it
ndash For non-tablet-specific titles we can take advantage of NativeActivity without becoming incompatible
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Platform-specific Resources
Using NativeActivity Compatibly
27
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dV0WcQBII0d++++cBII0+81[8IRG58C6B64[dR69cQBII0dcQ6WI96Wd
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dR69cQBII0d++++cBII0+81[8IRG58C6B64[dV0WcQBII0dcQ6WI96Wd
Using NativeActivity Compatibly
28
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
cR5N5R2+846I54)81[Kgt$XR5N$R5N5R2[+++846I54)8B04[^BII0QRWRG58C6B64[d++c1R34R+846I54)81[846I54KLLK05B81[+++++846I54)N09[W8R5N[+Qd++++++++++++++++++++++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6d++++++++++++cQR5N5R2dcR5N5R2+846I54)81[K1I$R5N5R2[+++846I54)8B04[^BII0Q8IRG58C6B64[d++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6dcQR5N5R2d
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+W8R5N$F$Ggt+)+3$XltJXm$gtltFJgt+ )+C09R50WK+k+ LL3846I5438R5NK$JMgt+)+30GgtND+3040+300IC+30G+30846I54$gt$JJMlt$ltJgt+ )+846I548R5NLLC09$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7-00+51LI6R31I490a846I54Q8R5NLLC097
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
LTC+I1KY1L0KW88C0WU
L9B05+0WW+gt$XR5N$R5N5R2+YR84W+846I54KLLKXR5N$R5N5R2+Z
++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
LTC+I1KY1L0KW88C0WU
L9B05+0WW+1I$R5N5R2+YR84W+846I54KLLK$R5N5R2+Z++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++++++gt2WR1K0I45B662-[WE85[7U++++KKK
Key Game Components
33
Lifecycle
Graphics Sound
Input
Assets
Activity LifecycleLifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Process LifecycleLifecycle
Android keeps application processes around for as long as possible
ndash Even when the activity is closed with V585W`-7 or the back key is pressed
The foreground activity process is considered the most important
ndash It can still be killed as a last resort
Visible activities are also given high priority
ndash Backgrounded activities are considered less important
ndash Processes with no active activities are killed first
Implications of the Process LifecycleLifecycle
Be careful with static initializers
ndash Your library cannot be unloaded while your process is active
bull Donrsquot assume that your static initializers will be run when your activity is created
Be careful with threads
ndash Threads are tied to the process not the activity
bull Your threads will continue to run at reduced priority even if your activity is backgrounded or destroyed
ndash Gameplay should stop during onPause
bull It might make sense to keep certain threads running - your activity may still be visible
ndash Make sure all native code is cleaned up during onDestroy
bull Users expect that your application will no longer be active when its activity is destroyed
The Basics
Key handling
ndash Your device most likely has capacitive buttons
bull Look for complete state transitions of I8m2I_8I8m2AL
bull Avoid overriding 45WLR`m2N8R
ndash Use I8m290R5L0I8m2I8Camp6WW
bull Keep your game behaving like an Android application
TouchMultitouch handling
ndash With I8I9`N8R
bull take advantage of built-in gesture processing
ndash use gt0GWR96RRI6 and GWR96RRI6
ndash Most devices now support multitouch
bull determine if your device can track distinct points
ndash `Wgt2WR1FR96-F$AltA(gtltXAJA(JgtJX)
37
Input
Other Input
Trackball handling
ndash With I86TB00N8R
bull Unhandled events turn into dpad events
Motion handling
ndash With I8gt8WI6`8C4
bull Must be registered with the gt8WI68C6
bull Disable unneeded sensors especially when paused
ndash Active sensors will quickly drain the battery
38
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
OpenGL
GLSurfaceView
ndash Creates the compatible context
bull Contexts are shared between native code and Dalvik
ndash Creates a rendering thread
ndash Releases the context during onPause
ndash Not the most efficient way to multitask withOpenGL but it avoids some driver issues
When context is lost
ndash Reload resources
bull Textures
bull Buffer objects
bull Shaders
ndash Names donrsquot persist
40
Graphics
Texture Formats
Android encourages innovation in hardware
ndash Chipset vendors use several kinds of proprietary texture compression formats
ndash OpenGL ES supports multiple compressed formats none mandatory
Solutions
ndash Uncompressed Textures
ndash Use ETC1 ndash broad support in 20
bull Optimized around photographic data
bull No Alpha
ndash Use Multi-APK (coming soon)
ndash Put textures on an asset server
bull Detect support at runtime
bull Download to each device
41
Graphics
Drawing for Performance
Draw order is important
ndash Has no impact on some platforms means everything on others
ndash Draw front to back to make best use of early rejects
Use VBOs
ndash Avoid unnecessary state changes
Textures
ndash Use power of 2 sized textures
bull It can be very slow
bull On some chipsets not all address modes work
42
Graphics
Writing Compatible Shaders
Query query
ndash Make sure to query for number of attributes varying and uniforms supported
bull Varies between devices
bull Not respecting will make your application crash
bull ldquoSupportedrdquo does not mean ldquoperforms wellrdquo
Conditions
ndash Avoid as much as possible
bull if necessary put them last in the shader
ndash Use mix() clamp() etc to create the same result
discard()
ndash Avoid discard()
bull if necessary it should be last
43
Graphics
Audio Solutions
Full track audio
s 45amp026
bull Plays multiple formats with codec support
bull Plays from filesystem or from network
bull Has high latency memory and CPU usage for quick sound effects
Sound effects and clips
s gtI984ampII0
bull Plays multiple formats with codec support
bull Preloads audio files to a pool
ndash Plays them with low latency
44
Sound
Audio Solutions
Application-generated audio
s $945I6T
bull Plays PCM audio only with minimal latency
bull Useful for applications that wish to perform sound processing or mixing
OpenSLES
ndash Combines capabilities of 45amp026 and $945I6T
ndash Available only in the NDK
ndash Requires Android 23 and higher
45
Sound
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
Use native AssetManager
ndash Gingerbread and Beyond
Targeting tricky trying tasks
Troubleshooting Tips and Tricks
47
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
One JNI Context Per Thread
Threading Options
49
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
JNI Context 2
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
OR
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
If all else fails Market filters
ndash Instruction set
ndash ARMv5ARMv7
ndash GL version
ndash Platform release
ndash Use Device Availability
Tips Standing Out from the Crowd
Start Small
ndash Download assets as-needed
ndash Hook me early instead of making me wait
Use Android backuprestore service (save to the cloud)
ndash Keep my progress when I switch devices
Support multiple control schemes
ndash Trackball D-pad virtual stick
ndash Let me decide what works best
Support install-to-SD
ndash Android Market users will knock your ratings if you donrsquot
51
Tips Standing Out from the Crowd
Profiling
ndash In-game profiling to select optimal settings per-device
Social
ndash Hook into social networks
ndash Use OpenID
Build a live wallpaper
ndash Own the userrsquos home screen with stats avatars
Analytics
ndash Market and in-game
In-app payments
ndash Consider alternative monetization techniques
52
Troubleshooting Development Tools
NVIDIA Debug Manager for Eclipse
ndash Simplifies setup for native debugger under Eclipse
bull developernvidiacomtegranvidia-debug-manager-android-ndk
WinGDB
ndash Use Visual Studio to debug Android NDK applications
bull wwwwingdbcom
vs-android
ndash Native MSBuild files for Android toolchain
bull vs-androidgooglecodecom
53
Troubleshooting Performance Tools
NVIDIA PerfHUD ES
ndash developernvidiacomtegraperfhud-es
Adreno Profiler
ndash developerqualcommcomshowcaseadreno-profiler
POWERVR Insider Utilities
ndash Including PVRTrace and PVRTune
ndash wwwimgteccompowervrinsiderpowervr-utilitiesasp
54
developerandroidcomsdkndkGoogleGameDevAndroid
Feedback httpgooglNudVs
QampA
55
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
PXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]LPXJ8Na+EIBER+IBEa+E58R+a+E58R+B7+Z
++E0WW+0W++-]LPXJ8N73dGRBER0WW-LPXJ8Na+IBE7U
++E1R`I4J+54++-]LPXJ8N73dGRR`I4J-+++++++++++++++++++++++++++++LPXJ8Na+0Wa+[RTm2N8RW[a+[-n7=[7U
++-]LPXJ8N73d00=I54R`I4-LPXJ8Na+IBEa+54a+PXJltA7U
Development Flow Calling Dalvik Code Within CC++
20
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Build and Deploy
gt=0Alt-amp49BCDBEFG6HI
ndash Builds C libraries and emits so files
gt)-3
ndash (or ant release)
ndash Builds Java classes apk package
gtamp=44
ndash Deploys to emulator or device
21
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdbgdb-rsp over named pipe
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdb
EclipseVS
gdb-rsp over named pipe
gdb-MI
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Important Tip
B)-36amp3)$$)J23
Bringing Your Game to Android
24
Devices Accessing Android Market
25
Android 16
Android 15
Android 23
Android 233
Android 30
Two Week Period Published May 2011
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
NativeActivity is just starting
ndash 43 of checking-in devices can utilize it
ndash For non-tablet-specific titles we can take advantage of NativeActivity without becoming incompatible
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Platform-specific Resources
Using NativeActivity Compatibly
27
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dV0WcQBII0d++++cBII0+81[8IRG58C6B64[dR69cQBII0dcQ6WI96Wd
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dR69cQBII0d++++cBII0+81[8IRG58C6B64[dV0WcQBII0dcQ6WI96Wd
Using NativeActivity Compatibly
28
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
cR5N5R2+846I54)81[Kgt$XR5N$R5N5R2[+++846I54)8B04[^BII0QRWRG58C6B64[d++c1R34R+846I54)81[846I54KLLK05B81[+++++846I54)N09[W8R5N[+Qd++++++++++++++++++++++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6d++++++++++++cQR5N5R2dcR5N5R2+846I54)81[K1I$R5N5R2[+++846I54)8B04[^BII0Q8IRG58C6B64[d++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6dcQR5N5R2d
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+W8R5N$F$Ggt+)+3$XltJXm$gtltFJgt+ )+C09R50WK+k+ LL3846I5438R5NK$JMgt+)+30GgtND+3040+300IC+30G+30846I54$gt$JJMlt$ltJgt+ )+846I548R5NLLC09$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7-00+51LI6R31I490a846I54Q8R5NLLC097
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
LTC+I1KY1L0KW88C0WU
L9B05+0WW+gt$XR5N$R5N5R2+YR84W+846I54KLLKXR5N$R5N5R2+Z
++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
LTC+I1KY1L0KW88C0WU
L9B05+0WW+1I$R5N5R2+YR84W+846I54KLLK$R5N5R2+Z++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++++++gt2WR1K0I45B662-[WE85[7U++++KKK
Key Game Components
33
Lifecycle
Graphics Sound
Input
Assets
Activity LifecycleLifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Process LifecycleLifecycle
Android keeps application processes around for as long as possible
ndash Even when the activity is closed with V585W`-7 or the back key is pressed
The foreground activity process is considered the most important
ndash It can still be killed as a last resort
Visible activities are also given high priority
ndash Backgrounded activities are considered less important
ndash Processes with no active activities are killed first
Implications of the Process LifecycleLifecycle
Be careful with static initializers
ndash Your library cannot be unloaded while your process is active
bull Donrsquot assume that your static initializers will be run when your activity is created
Be careful with threads
ndash Threads are tied to the process not the activity
bull Your threads will continue to run at reduced priority even if your activity is backgrounded or destroyed
ndash Gameplay should stop during onPause
bull It might make sense to keep certain threads running - your activity may still be visible
ndash Make sure all native code is cleaned up during onDestroy
bull Users expect that your application will no longer be active when its activity is destroyed
The Basics
Key handling
ndash Your device most likely has capacitive buttons
bull Look for complete state transitions of I8m2I_8I8m2AL
bull Avoid overriding 45WLR`m2N8R
ndash Use I8m290R5L0I8m2I8Camp6WW
bull Keep your game behaving like an Android application
TouchMultitouch handling
ndash With I8I9`N8R
bull take advantage of built-in gesture processing
ndash use gt0GWR96RRI6 and GWR96RRI6
ndash Most devices now support multitouch
bull determine if your device can track distinct points
ndash `Wgt2WR1FR96-F$AltA(gtltXAJA(JgtJX)
37
Input
Other Input
Trackball handling
ndash With I86TB00N8R
bull Unhandled events turn into dpad events
Motion handling
ndash With I8gt8WI6`8C4
bull Must be registered with the gt8WI68C6
bull Disable unneeded sensors especially when paused
ndash Active sensors will quickly drain the battery
38
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
OpenGL
GLSurfaceView
ndash Creates the compatible context
bull Contexts are shared between native code and Dalvik
ndash Creates a rendering thread
ndash Releases the context during onPause
ndash Not the most efficient way to multitask withOpenGL but it avoids some driver issues
When context is lost
ndash Reload resources
bull Textures
bull Buffer objects
bull Shaders
ndash Names donrsquot persist
40
Graphics
Texture Formats
Android encourages innovation in hardware
ndash Chipset vendors use several kinds of proprietary texture compression formats
ndash OpenGL ES supports multiple compressed formats none mandatory
Solutions
ndash Uncompressed Textures
ndash Use ETC1 ndash broad support in 20
bull Optimized around photographic data
bull No Alpha
ndash Use Multi-APK (coming soon)
ndash Put textures on an asset server
bull Detect support at runtime
bull Download to each device
41
Graphics
Drawing for Performance
Draw order is important
ndash Has no impact on some platforms means everything on others
ndash Draw front to back to make best use of early rejects
Use VBOs
ndash Avoid unnecessary state changes
Textures
ndash Use power of 2 sized textures
bull It can be very slow
bull On some chipsets not all address modes work
42
Graphics
Writing Compatible Shaders
Query query
ndash Make sure to query for number of attributes varying and uniforms supported
bull Varies between devices
bull Not respecting will make your application crash
bull ldquoSupportedrdquo does not mean ldquoperforms wellrdquo
Conditions
ndash Avoid as much as possible
bull if necessary put them last in the shader
ndash Use mix() clamp() etc to create the same result
discard()
ndash Avoid discard()
bull if necessary it should be last
43
Graphics
Audio Solutions
Full track audio
s 45amp026
bull Plays multiple formats with codec support
bull Plays from filesystem or from network
bull Has high latency memory and CPU usage for quick sound effects
Sound effects and clips
s gtI984ampII0
bull Plays multiple formats with codec support
bull Preloads audio files to a pool
ndash Plays them with low latency
44
Sound
Audio Solutions
Application-generated audio
s $945I6T
bull Plays PCM audio only with minimal latency
bull Useful for applications that wish to perform sound processing or mixing
OpenSLES
ndash Combines capabilities of 45amp026 and $945I6T
ndash Available only in the NDK
ndash Requires Android 23 and higher
45
Sound
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
Use native AssetManager
ndash Gingerbread and Beyond
Targeting tricky trying tasks
Troubleshooting Tips and Tricks
47
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
One JNI Context Per Thread
Threading Options
49
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
JNI Context 2
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
OR
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
If all else fails Market filters
ndash Instruction set
ndash ARMv5ARMv7
ndash GL version
ndash Platform release
ndash Use Device Availability
Tips Standing Out from the Crowd
Start Small
ndash Download assets as-needed
ndash Hook me early instead of making me wait
Use Android backuprestore service (save to the cloud)
ndash Keep my progress when I switch devices
Support multiple control schemes
ndash Trackball D-pad virtual stick
ndash Let me decide what works best
Support install-to-SD
ndash Android Market users will knock your ratings if you donrsquot
51
Tips Standing Out from the Crowd
Profiling
ndash In-game profiling to select optimal settings per-device
Social
ndash Hook into social networks
ndash Use OpenID
Build a live wallpaper
ndash Own the userrsquos home screen with stats avatars
Analytics
ndash Market and in-game
In-app payments
ndash Consider alternative monetization techniques
52
Troubleshooting Development Tools
NVIDIA Debug Manager for Eclipse
ndash Simplifies setup for native debugger under Eclipse
bull developernvidiacomtegranvidia-debug-manager-android-ndk
WinGDB
ndash Use Visual Studio to debug Android NDK applications
bull wwwwingdbcom
vs-android
ndash Native MSBuild files for Android toolchain
bull vs-androidgooglecodecom
53
Troubleshooting Performance Tools
NVIDIA PerfHUD ES
ndash developernvidiacomtegraperfhud-es
Adreno Profiler
ndash developerqualcommcomshowcaseadreno-profiler
POWERVR Insider Utilities
ndash Including PVRTrace and PVRTune
ndash wwwimgteccompowervrinsiderpowervr-utilitiesasp
54
developerandroidcomsdkndkGoogleGameDevAndroid
Feedback httpgooglNudVs
QampA
55
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
PXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]LPXJ8Na+EIBER+IBEa+E58R+a+E58R+B7+Z
++E0WW+0W++-]LPXJ8N73dGRBER0WW-LPXJ8Na+IBE7U
++E1R`I4J+54++-]LPXJ8N73dGRR`I4J-+++++++++++++++++++++++++++++LPXJ8Na+0Wa+[RTm2N8RW[a+[-n7=[7U
++-]LPXJ8N73d00=I54R`I4-LPXJ8Na+IBEa+54a+PXJltA7U
Development Flow Calling Dalvik Code Within CC++
20
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Build and Deploy
gt=0Alt-amp49BCDBEFG6HI
ndash Builds C libraries and emits so files
gt)-3
ndash (or ant release)
ndash Builds Java classes apk package
gtamp=44
ndash Deploys to emulator or device
21
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdbgdb-rsp over named pipe
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdb
EclipseVS
gdb-rsp over named pipe
gdb-MI
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Important Tip
B)-36amp3)$$)J23
Bringing Your Game to Android
24
Devices Accessing Android Market
25
Android 16
Android 15
Android 23
Android 233
Android 30
Two Week Period Published May 2011
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
NativeActivity is just starting
ndash 43 of checking-in devices can utilize it
ndash For non-tablet-specific titles we can take advantage of NativeActivity without becoming incompatible
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Platform-specific Resources
Using NativeActivity Compatibly
27
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dV0WcQBII0d++++cBII0+81[8IRG58C6B64[dR69cQBII0dcQ6WI96Wd
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dR69cQBII0d++++cBII0+81[8IRG58C6B64[dV0WcQBII0dcQ6WI96Wd
Using NativeActivity Compatibly
28
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
cR5N5R2+846I54)81[Kgt$XR5N$R5N5R2[+++846I54)8B04[^BII0QRWRG58C6B64[d++c1R34R+846I54)81[846I54KLLK05B81[+++++846I54)N09[W8R5N[+Qd++++++++++++++++++++++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6d++++++++++++cQR5N5R2dcR5N5R2+846I54)81[K1I$R5N5R2[+++846I54)8B04[^BII0Q8IRG58C6B64[d++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6dcQR5N5R2d
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+W8R5N$F$Ggt+)+3$XltJXm$gtltFJgt+ )+C09R50WK+k+ LL3846I5438R5NK$JMgt+)+30GgtND+3040+300IC+30G+30846I54$gt$JJMlt$ltJgt+ )+846I548R5NLLC09$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7-00+51LI6R31I490a846I54Q8R5NLLC097
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
LTC+I1KY1L0KW88C0WU
L9B05+0WW+gt$XR5N$R5N5R2+YR84W+846I54KLLKXR5N$R5N5R2+Z
++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
LTC+I1KY1L0KW88C0WU
L9B05+0WW+1I$R5N5R2+YR84W+846I54KLLK$R5N5R2+Z++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++++++gt2WR1K0I45B662-[WE85[7U++++KKK
Key Game Components
33
Lifecycle
Graphics Sound
Input
Assets
Activity LifecycleLifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Process LifecycleLifecycle
Android keeps application processes around for as long as possible
ndash Even when the activity is closed with V585W`-7 or the back key is pressed
The foreground activity process is considered the most important
ndash It can still be killed as a last resort
Visible activities are also given high priority
ndash Backgrounded activities are considered less important
ndash Processes with no active activities are killed first
Implications of the Process LifecycleLifecycle
Be careful with static initializers
ndash Your library cannot be unloaded while your process is active
bull Donrsquot assume that your static initializers will be run when your activity is created
Be careful with threads
ndash Threads are tied to the process not the activity
bull Your threads will continue to run at reduced priority even if your activity is backgrounded or destroyed
ndash Gameplay should stop during onPause
bull It might make sense to keep certain threads running - your activity may still be visible
ndash Make sure all native code is cleaned up during onDestroy
bull Users expect that your application will no longer be active when its activity is destroyed
The Basics
Key handling
ndash Your device most likely has capacitive buttons
bull Look for complete state transitions of I8m2I_8I8m2AL
bull Avoid overriding 45WLR`m2N8R
ndash Use I8m290R5L0I8m2I8Camp6WW
bull Keep your game behaving like an Android application
TouchMultitouch handling
ndash With I8I9`N8R
bull take advantage of built-in gesture processing
ndash use gt0GWR96RRI6 and GWR96RRI6
ndash Most devices now support multitouch
bull determine if your device can track distinct points
ndash `Wgt2WR1FR96-F$AltA(gtltXAJA(JgtJX)
37
Input
Other Input
Trackball handling
ndash With I86TB00N8R
bull Unhandled events turn into dpad events
Motion handling
ndash With I8gt8WI6`8C4
bull Must be registered with the gt8WI68C6
bull Disable unneeded sensors especially when paused
ndash Active sensors will quickly drain the battery
38
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
OpenGL
GLSurfaceView
ndash Creates the compatible context
bull Contexts are shared between native code and Dalvik
ndash Creates a rendering thread
ndash Releases the context during onPause
ndash Not the most efficient way to multitask withOpenGL but it avoids some driver issues
When context is lost
ndash Reload resources
bull Textures
bull Buffer objects
bull Shaders
ndash Names donrsquot persist
40
Graphics
Texture Formats
Android encourages innovation in hardware
ndash Chipset vendors use several kinds of proprietary texture compression formats
ndash OpenGL ES supports multiple compressed formats none mandatory
Solutions
ndash Uncompressed Textures
ndash Use ETC1 ndash broad support in 20
bull Optimized around photographic data
bull No Alpha
ndash Use Multi-APK (coming soon)
ndash Put textures on an asset server
bull Detect support at runtime
bull Download to each device
41
Graphics
Drawing for Performance
Draw order is important
ndash Has no impact on some platforms means everything on others
ndash Draw front to back to make best use of early rejects
Use VBOs
ndash Avoid unnecessary state changes
Textures
ndash Use power of 2 sized textures
bull It can be very slow
bull On some chipsets not all address modes work
42
Graphics
Writing Compatible Shaders
Query query
ndash Make sure to query for number of attributes varying and uniforms supported
bull Varies between devices
bull Not respecting will make your application crash
bull ldquoSupportedrdquo does not mean ldquoperforms wellrdquo
Conditions
ndash Avoid as much as possible
bull if necessary put them last in the shader
ndash Use mix() clamp() etc to create the same result
discard()
ndash Avoid discard()
bull if necessary it should be last
43
Graphics
Audio Solutions
Full track audio
s 45amp026
bull Plays multiple formats with codec support
bull Plays from filesystem or from network
bull Has high latency memory and CPU usage for quick sound effects
Sound effects and clips
s gtI984ampII0
bull Plays multiple formats with codec support
bull Preloads audio files to a pool
ndash Plays them with low latency
44
Sound
Audio Solutions
Application-generated audio
s $945I6T
bull Plays PCM audio only with minimal latency
bull Useful for applications that wish to perform sound processing or mixing
OpenSLES
ndash Combines capabilities of 45amp026 and $945I6T
ndash Available only in the NDK
ndash Requires Android 23 and higher
45
Sound
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
Use native AssetManager
ndash Gingerbread and Beyond
Targeting tricky trying tasks
Troubleshooting Tips and Tricks
47
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
One JNI Context Per Thread
Threading Options
49
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
JNI Context 2
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
OR
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
If all else fails Market filters
ndash Instruction set
ndash ARMv5ARMv7
ndash GL version
ndash Platform release
ndash Use Device Availability
Tips Standing Out from the Crowd
Start Small
ndash Download assets as-needed
ndash Hook me early instead of making me wait
Use Android backuprestore service (save to the cloud)
ndash Keep my progress when I switch devices
Support multiple control schemes
ndash Trackball D-pad virtual stick
ndash Let me decide what works best
Support install-to-SD
ndash Android Market users will knock your ratings if you donrsquot
51
Tips Standing Out from the Crowd
Profiling
ndash In-game profiling to select optimal settings per-device
Social
ndash Hook into social networks
ndash Use OpenID
Build a live wallpaper
ndash Own the userrsquos home screen with stats avatars
Analytics
ndash Market and in-game
In-app payments
ndash Consider alternative monetization techniques
52
Troubleshooting Development Tools
NVIDIA Debug Manager for Eclipse
ndash Simplifies setup for native debugger under Eclipse
bull developernvidiacomtegranvidia-debug-manager-android-ndk
WinGDB
ndash Use Visual Studio to debug Android NDK applications
bull wwwwingdbcom
vs-android
ndash Native MSBuild files for Android toolchain
bull vs-androidgooglecodecom
53
Troubleshooting Performance Tools
NVIDIA PerfHUD ES
ndash developernvidiacomtegraperfhud-es
Adreno Profiler
ndash developerqualcommcomshowcaseadreno-profiler
POWERVR Insider Utilities
ndash Including PVRTrace and PVRTune
ndash wwwimgteccompowervrinsiderpowervr-utilitiesasp
54
developerandroidcomsdkndkGoogleGameDevAndroid
Feedback httpgooglNudVs
QampA
55
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
PXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]LPXJ8Na+EIBER+IBEa+E58R+a+E58R+B7+Z
++E0WW+0W++-]LPXJ8N73dGRBER0WW-LPXJ8Na+IBE7U
++E1R`I4J+54++-]LPXJ8N73dGRR`I4J-+++++++++++++++++++++++++++++LPXJ8Na+0Wa+[RTm2N8RW[a+[-n7=[7U
++-]LPXJ8N73d00=I54R`I4-LPXJ8Na+IBEa+54a+PXJltA7U
Development Flow Calling Dalvik Code Within CC++
20
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Build and Deploy
gt=0Alt-amp49BCDBEFG6HI
ndash Builds C libraries and emits so files
gt)-3
ndash (or ant release)
ndash Builds Java classes apk package
gtamp=44
ndash Deploys to emulator or device
21
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdbgdb-rsp over named pipe
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdb
EclipseVS
gdb-rsp over named pipe
gdb-MI
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Important Tip
B)-36amp3)$$)J23
Bringing Your Game to Android
24
Devices Accessing Android Market
25
Android 16
Android 15
Android 23
Android 233
Android 30
Two Week Period Published May 2011
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
NativeActivity is just starting
ndash 43 of checking-in devices can utilize it
ndash For non-tablet-specific titles we can take advantage of NativeActivity without becoming incompatible
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Platform-specific Resources
Using NativeActivity Compatibly
27
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dV0WcQBII0d++++cBII0+81[8IRG58C6B64[dR69cQBII0dcQ6WI96Wd
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dR69cQBII0d++++cBII0+81[8IRG58C6B64[dV0WcQBII0dcQ6WI96Wd
Using NativeActivity Compatibly
28
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
cR5N5R2+846I54)81[Kgt$XR5N$R5N5R2[+++846I54)8B04[^BII0QRWRG58C6B64[d++c1R34R+846I54)81[846I54KLLK05B81[+++++846I54)N09[W8R5N[+Qd++++++++++++++++++++++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6d++++++++++++cQR5N5R2dcR5N5R2+846I54)81[K1I$R5N5R2[+++846I54)8B04[^BII0Q8IRG58C6B64[d++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6dcQR5N5R2d
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+W8R5N$F$Ggt+)+3$XltJXm$gtltFJgt+ )+C09R50WK+k+ LL3846I5438R5NK$JMgt+)+30GgtND+3040+300IC+30G+30846I54$gt$JJMlt$ltJgt+ )+846I548R5NLLC09$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7-00+51LI6R31I490a846I54Q8R5NLLC097
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
LTC+I1KY1L0KW88C0WU
L9B05+0WW+gt$XR5N$R5N5R2+YR84W+846I54KLLKXR5N$R5N5R2+Z
++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
LTC+I1KY1L0KW88C0WU
L9B05+0WW+1I$R5N5R2+YR84W+846I54KLLK$R5N5R2+Z++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++++++gt2WR1K0I45B662-[WE85[7U++++KKK
Key Game Components
33
Lifecycle
Graphics Sound
Input
Assets
Activity LifecycleLifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Process LifecycleLifecycle
Android keeps application processes around for as long as possible
ndash Even when the activity is closed with V585W`-7 or the back key is pressed
The foreground activity process is considered the most important
ndash It can still be killed as a last resort
Visible activities are also given high priority
ndash Backgrounded activities are considered less important
ndash Processes with no active activities are killed first
Implications of the Process LifecycleLifecycle
Be careful with static initializers
ndash Your library cannot be unloaded while your process is active
bull Donrsquot assume that your static initializers will be run when your activity is created
Be careful with threads
ndash Threads are tied to the process not the activity
bull Your threads will continue to run at reduced priority even if your activity is backgrounded or destroyed
ndash Gameplay should stop during onPause
bull It might make sense to keep certain threads running - your activity may still be visible
ndash Make sure all native code is cleaned up during onDestroy
bull Users expect that your application will no longer be active when its activity is destroyed
The Basics
Key handling
ndash Your device most likely has capacitive buttons
bull Look for complete state transitions of I8m2I_8I8m2AL
bull Avoid overriding 45WLR`m2N8R
ndash Use I8m290R5L0I8m2I8Camp6WW
bull Keep your game behaving like an Android application
TouchMultitouch handling
ndash With I8I9`N8R
bull take advantage of built-in gesture processing
ndash use gt0GWR96RRI6 and GWR96RRI6
ndash Most devices now support multitouch
bull determine if your device can track distinct points
ndash `Wgt2WR1FR96-F$AltA(gtltXAJA(JgtJX)
37
Input
Other Input
Trackball handling
ndash With I86TB00N8R
bull Unhandled events turn into dpad events
Motion handling
ndash With I8gt8WI6`8C4
bull Must be registered with the gt8WI68C6
bull Disable unneeded sensors especially when paused
ndash Active sensors will quickly drain the battery
38
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
OpenGL
GLSurfaceView
ndash Creates the compatible context
bull Contexts are shared between native code and Dalvik
ndash Creates a rendering thread
ndash Releases the context during onPause
ndash Not the most efficient way to multitask withOpenGL but it avoids some driver issues
When context is lost
ndash Reload resources
bull Textures
bull Buffer objects
bull Shaders
ndash Names donrsquot persist
40
Graphics
Texture Formats
Android encourages innovation in hardware
ndash Chipset vendors use several kinds of proprietary texture compression formats
ndash OpenGL ES supports multiple compressed formats none mandatory
Solutions
ndash Uncompressed Textures
ndash Use ETC1 ndash broad support in 20
bull Optimized around photographic data
bull No Alpha
ndash Use Multi-APK (coming soon)
ndash Put textures on an asset server
bull Detect support at runtime
bull Download to each device
41
Graphics
Drawing for Performance
Draw order is important
ndash Has no impact on some platforms means everything on others
ndash Draw front to back to make best use of early rejects
Use VBOs
ndash Avoid unnecessary state changes
Textures
ndash Use power of 2 sized textures
bull It can be very slow
bull On some chipsets not all address modes work
42
Graphics
Writing Compatible Shaders
Query query
ndash Make sure to query for number of attributes varying and uniforms supported
bull Varies between devices
bull Not respecting will make your application crash
bull ldquoSupportedrdquo does not mean ldquoperforms wellrdquo
Conditions
ndash Avoid as much as possible
bull if necessary put them last in the shader
ndash Use mix() clamp() etc to create the same result
discard()
ndash Avoid discard()
bull if necessary it should be last
43
Graphics
Audio Solutions
Full track audio
s 45amp026
bull Plays multiple formats with codec support
bull Plays from filesystem or from network
bull Has high latency memory and CPU usage for quick sound effects
Sound effects and clips
s gtI984ampII0
bull Plays multiple formats with codec support
bull Preloads audio files to a pool
ndash Plays them with low latency
44
Sound
Audio Solutions
Application-generated audio
s $945I6T
bull Plays PCM audio only with minimal latency
bull Useful for applications that wish to perform sound processing or mixing
OpenSLES
ndash Combines capabilities of 45amp026 and $945I6T
ndash Available only in the NDK
ndash Requires Android 23 and higher
45
Sound
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
Use native AssetManager
ndash Gingerbread and Beyond
Targeting tricky trying tasks
Troubleshooting Tips and Tricks
47
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
One JNI Context Per Thread
Threading Options
49
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
JNI Context 2
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
OR
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
If all else fails Market filters
ndash Instruction set
ndash ARMv5ARMv7
ndash GL version
ndash Platform release
ndash Use Device Availability
Tips Standing Out from the Crowd
Start Small
ndash Download assets as-needed
ndash Hook me early instead of making me wait
Use Android backuprestore service (save to the cloud)
ndash Keep my progress when I switch devices
Support multiple control schemes
ndash Trackball D-pad virtual stick
ndash Let me decide what works best
Support install-to-SD
ndash Android Market users will knock your ratings if you donrsquot
51
Tips Standing Out from the Crowd
Profiling
ndash In-game profiling to select optimal settings per-device
Social
ndash Hook into social networks
ndash Use OpenID
Build a live wallpaper
ndash Own the userrsquos home screen with stats avatars
Analytics
ndash Market and in-game
In-app payments
ndash Consider alternative monetization techniques
52
Troubleshooting Development Tools
NVIDIA Debug Manager for Eclipse
ndash Simplifies setup for native debugger under Eclipse
bull developernvidiacomtegranvidia-debug-manager-android-ndk
WinGDB
ndash Use Visual Studio to debug Android NDK applications
bull wwwwingdbcom
vs-android
ndash Native MSBuild files for Android toolchain
bull vs-androidgooglecodecom
53
Troubleshooting Performance Tools
NVIDIA PerfHUD ES
ndash developernvidiacomtegraperfhud-es
Adreno Profiler
ndash developerqualcommcomshowcaseadreno-profiler
POWERVR Insider Utilities
ndash Including PVRTrace and PVRTune
ndash wwwimgteccompowervrinsiderpowervr-utilitiesasp
54
developerandroidcomsdkndkGoogleGameDevAndroid
Feedback httpgooglNudVs
QampA
55
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
PXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]LPXJ8Na+EIBER+IBEa+E58R+a+E58R+B7+Z
++E0WW+0W++-]LPXJ8N73dGRBER0WW-LPXJ8Na+IBE7U
++E1R`I4J+54++-]LPXJ8N73dGRR`I4J-+++++++++++++++++++++++++++++LPXJ8Na+0Wa+[RTm2N8RW[a+[-n7=[7U
++-]LPXJ8N73d00=I54R`I4-LPXJ8Na+IBEa+54a+PXJltA7U
Development Flow Calling Dalvik Code Within CC++
20
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Build and Deploy
gt=0Alt-amp49BCDBEFG6HI
ndash Builds C libraries and emits so files
gt)-3
ndash (or ant release)
ndash Builds Java classes apk package
gtamp=44
ndash Deploys to emulator or device
21
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdbgdb-rsp over named pipe
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdb
EclipseVS
gdb-rsp over named pipe
gdb-MI
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Important Tip
B)-36amp3)$$)J23
Bringing Your Game to Android
24
Devices Accessing Android Market
25
Android 16
Android 15
Android 23
Android 233
Android 30
Two Week Period Published May 2011
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
NativeActivity is just starting
ndash 43 of checking-in devices can utilize it
ndash For non-tablet-specific titles we can take advantage of NativeActivity without becoming incompatible
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Platform-specific Resources
Using NativeActivity Compatibly
27
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dV0WcQBII0d++++cBII0+81[8IRG58C6B64[dR69cQBII0dcQ6WI96Wd
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dR69cQBII0d++++cBII0+81[8IRG58C6B64[dV0WcQBII0dcQ6WI96Wd
Using NativeActivity Compatibly
28
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
cR5N5R2+846I54)81[Kgt$XR5N$R5N5R2[+++846I54)8B04[^BII0QRWRG58C6B64[d++c1R34R+846I54)81[846I54KLLK05B81[+++++846I54)N09[W8R5N[+Qd++++++++++++++++++++++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6d++++++++++++cQR5N5R2dcR5N5R2+846I54)81[K1I$R5N5R2[+++846I54)8B04[^BII0Q8IRG58C6B64[d++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6dcQR5N5R2d
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+W8R5N$F$Ggt+)+3$XltJXm$gtltFJgt+ )+C09R50WK+k+ LL3846I5438R5NK$JMgt+)+30GgtND+3040+300IC+30G+30846I54$gt$JJMlt$ltJgt+ )+846I548R5NLLC09$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7-00+51LI6R31I490a846I54Q8R5NLLC097
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
LTC+I1KY1L0KW88C0WU
L9B05+0WW+gt$XR5N$R5N5R2+YR84W+846I54KLLKXR5N$R5N5R2+Z
++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
LTC+I1KY1L0KW88C0WU
L9B05+0WW+1I$R5N5R2+YR84W+846I54KLLK$R5N5R2+Z++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++++++gt2WR1K0I45B662-[WE85[7U++++KKK
Key Game Components
33
Lifecycle
Graphics Sound
Input
Assets
Activity LifecycleLifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Process LifecycleLifecycle
Android keeps application processes around for as long as possible
ndash Even when the activity is closed with V585W`-7 or the back key is pressed
The foreground activity process is considered the most important
ndash It can still be killed as a last resort
Visible activities are also given high priority
ndash Backgrounded activities are considered less important
ndash Processes with no active activities are killed first
Implications of the Process LifecycleLifecycle
Be careful with static initializers
ndash Your library cannot be unloaded while your process is active
bull Donrsquot assume that your static initializers will be run when your activity is created
Be careful with threads
ndash Threads are tied to the process not the activity
bull Your threads will continue to run at reduced priority even if your activity is backgrounded or destroyed
ndash Gameplay should stop during onPause
bull It might make sense to keep certain threads running - your activity may still be visible
ndash Make sure all native code is cleaned up during onDestroy
bull Users expect that your application will no longer be active when its activity is destroyed
The Basics
Key handling
ndash Your device most likely has capacitive buttons
bull Look for complete state transitions of I8m2I_8I8m2AL
bull Avoid overriding 45WLR`m2N8R
ndash Use I8m290R5L0I8m2I8Camp6WW
bull Keep your game behaving like an Android application
TouchMultitouch handling
ndash With I8I9`N8R
bull take advantage of built-in gesture processing
ndash use gt0GWR96RRI6 and GWR96RRI6
ndash Most devices now support multitouch
bull determine if your device can track distinct points
ndash `Wgt2WR1FR96-F$AltA(gtltXAJA(JgtJX)
37
Input
Other Input
Trackball handling
ndash With I86TB00N8R
bull Unhandled events turn into dpad events
Motion handling
ndash With I8gt8WI6`8C4
bull Must be registered with the gt8WI68C6
bull Disable unneeded sensors especially when paused
ndash Active sensors will quickly drain the battery
38
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
OpenGL
GLSurfaceView
ndash Creates the compatible context
bull Contexts are shared between native code and Dalvik
ndash Creates a rendering thread
ndash Releases the context during onPause
ndash Not the most efficient way to multitask withOpenGL but it avoids some driver issues
When context is lost
ndash Reload resources
bull Textures
bull Buffer objects
bull Shaders
ndash Names donrsquot persist
40
Graphics
Texture Formats
Android encourages innovation in hardware
ndash Chipset vendors use several kinds of proprietary texture compression formats
ndash OpenGL ES supports multiple compressed formats none mandatory
Solutions
ndash Uncompressed Textures
ndash Use ETC1 ndash broad support in 20
bull Optimized around photographic data
bull No Alpha
ndash Use Multi-APK (coming soon)
ndash Put textures on an asset server
bull Detect support at runtime
bull Download to each device
41
Graphics
Drawing for Performance
Draw order is important
ndash Has no impact on some platforms means everything on others
ndash Draw front to back to make best use of early rejects
Use VBOs
ndash Avoid unnecessary state changes
Textures
ndash Use power of 2 sized textures
bull It can be very slow
bull On some chipsets not all address modes work
42
Graphics
Writing Compatible Shaders
Query query
ndash Make sure to query for number of attributes varying and uniforms supported
bull Varies between devices
bull Not respecting will make your application crash
bull ldquoSupportedrdquo does not mean ldquoperforms wellrdquo
Conditions
ndash Avoid as much as possible
bull if necessary put them last in the shader
ndash Use mix() clamp() etc to create the same result
discard()
ndash Avoid discard()
bull if necessary it should be last
43
Graphics
Audio Solutions
Full track audio
s 45amp026
bull Plays multiple formats with codec support
bull Plays from filesystem or from network
bull Has high latency memory and CPU usage for quick sound effects
Sound effects and clips
s gtI984ampII0
bull Plays multiple formats with codec support
bull Preloads audio files to a pool
ndash Plays them with low latency
44
Sound
Audio Solutions
Application-generated audio
s $945I6T
bull Plays PCM audio only with minimal latency
bull Useful for applications that wish to perform sound processing or mixing
OpenSLES
ndash Combines capabilities of 45amp026 and $945I6T
ndash Available only in the NDK
ndash Requires Android 23 and higher
45
Sound
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
Use native AssetManager
ndash Gingerbread and Beyond
Targeting tricky trying tasks
Troubleshooting Tips and Tricks
47
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
One JNI Context Per Thread
Threading Options
49
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
JNI Context 2
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
OR
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
If all else fails Market filters
ndash Instruction set
ndash ARMv5ARMv7
ndash GL version
ndash Platform release
ndash Use Device Availability
Tips Standing Out from the Crowd
Start Small
ndash Download assets as-needed
ndash Hook me early instead of making me wait
Use Android backuprestore service (save to the cloud)
ndash Keep my progress when I switch devices
Support multiple control schemes
ndash Trackball D-pad virtual stick
ndash Let me decide what works best
Support install-to-SD
ndash Android Market users will knock your ratings if you donrsquot
51
Tips Standing Out from the Crowd
Profiling
ndash In-game profiling to select optimal settings per-device
Social
ndash Hook into social networks
ndash Use OpenID
Build a live wallpaper
ndash Own the userrsquos home screen with stats avatars
Analytics
ndash Market and in-game
In-app payments
ndash Consider alternative monetization techniques
52
Troubleshooting Development Tools
NVIDIA Debug Manager for Eclipse
ndash Simplifies setup for native debugger under Eclipse
bull developernvidiacomtegranvidia-debug-manager-android-ndk
WinGDB
ndash Use Visual Studio to debug Android NDK applications
bull wwwwingdbcom
vs-android
ndash Native MSBuild files for Android toolchain
bull vs-androidgooglecodecom
53
Troubleshooting Performance Tools
NVIDIA PerfHUD ES
ndash developernvidiacomtegraperfhud-es
Adreno Profiler
ndash developerqualcommcomshowcaseadreno-profiler
POWERVR Insider Utilities
ndash Including PVRTrace and PVRTune
ndash wwwimgteccompowervrinsiderpowervr-utilitiesasp
54
developerandroidcomsdkndkGoogleGameDevAndroid
Feedback httpgooglNudVs
QampA
55
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
PXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]LPXJ8Na+EIBER+IBEa+E58R+a+E58R+B7+Z
++E0WW+0W++-]LPXJ8N73dGRBER0WW-LPXJ8Na+IBE7U
++E1R`I4J+54++-]LPXJ8N73dGRR`I4J-+++++++++++++++++++++++++++++LPXJ8Na+0Wa+[RTm2N8RW[a+[-n7=[7U
++-]LPXJ8N73d00=I54R`I4-LPXJ8Na+IBEa+54a+PXJltA7U
Development Flow Calling Dalvik Code Within CC++
20
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Build and Deploy
gt=0Alt-amp49BCDBEFG6HI
ndash Builds C libraries and emits so files
gt)-3
ndash (or ant release)
ndash Builds Java classes apk package
gtamp=44
ndash Deploys to emulator or device
21
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdbgdb-rsp over named pipe
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdb
EclipseVS
gdb-rsp over named pipe
gdb-MI
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Important Tip
B)-36amp3)$$)J23
Bringing Your Game to Android
24
Devices Accessing Android Market
25
Android 16
Android 15
Android 23
Android 233
Android 30
Two Week Period Published May 2011
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
NativeActivity is just starting
ndash 43 of checking-in devices can utilize it
ndash For non-tablet-specific titles we can take advantage of NativeActivity without becoming incompatible
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Platform-specific Resources
Using NativeActivity Compatibly
27
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dV0WcQBII0d++++cBII0+81[8IRG58C6B64[dR69cQBII0dcQ6WI96Wd
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dR69cQBII0d++++cBII0+81[8IRG58C6B64[dV0WcQBII0dcQ6WI96Wd
Using NativeActivity Compatibly
28
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
cR5N5R2+846I54)81[Kgt$XR5N$R5N5R2[+++846I54)8B04[^BII0QRWRG58C6B64[d++c1R34R+846I54)81[846I54KLLK05B81[+++++846I54)N09[W8R5N[+Qd++++++++++++++++++++++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6d++++++++++++cQR5N5R2dcR5N5R2+846I54)81[K1I$R5N5R2[+++846I54)8B04[^BII0Q8IRG58C6B64[d++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6dcQR5N5R2d
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+W8R5N$F$Ggt+)+3$XltJXm$gtltFJgt+ )+C09R50WK+k+ LL3846I5438R5NK$JMgt+)+30GgtND+3040+300IC+30G+30846I54$gt$JJMlt$ltJgt+ )+846I548R5NLLC09$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7-00+51LI6R31I490a846I54Q8R5NLLC097
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
LTC+I1KY1L0KW88C0WU
L9B05+0WW+gt$XR5N$R5N5R2+YR84W+846I54KLLKXR5N$R5N5R2+Z
++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
LTC+I1KY1L0KW88C0WU
L9B05+0WW+1I$R5N5R2+YR84W+846I54KLLK$R5N5R2+Z++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++++++gt2WR1K0I45B662-[WE85[7U++++KKK
Key Game Components
33
Lifecycle
Graphics Sound
Input
Assets
Activity LifecycleLifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Process LifecycleLifecycle
Android keeps application processes around for as long as possible
ndash Even when the activity is closed with V585W`-7 or the back key is pressed
The foreground activity process is considered the most important
ndash It can still be killed as a last resort
Visible activities are also given high priority
ndash Backgrounded activities are considered less important
ndash Processes with no active activities are killed first
Implications of the Process LifecycleLifecycle
Be careful with static initializers
ndash Your library cannot be unloaded while your process is active
bull Donrsquot assume that your static initializers will be run when your activity is created
Be careful with threads
ndash Threads are tied to the process not the activity
bull Your threads will continue to run at reduced priority even if your activity is backgrounded or destroyed
ndash Gameplay should stop during onPause
bull It might make sense to keep certain threads running - your activity may still be visible
ndash Make sure all native code is cleaned up during onDestroy
bull Users expect that your application will no longer be active when its activity is destroyed
The Basics
Key handling
ndash Your device most likely has capacitive buttons
bull Look for complete state transitions of I8m2I_8I8m2AL
bull Avoid overriding 45WLR`m2N8R
ndash Use I8m290R5L0I8m2I8Camp6WW
bull Keep your game behaving like an Android application
TouchMultitouch handling
ndash With I8I9`N8R
bull take advantage of built-in gesture processing
ndash use gt0GWR96RRI6 and GWR96RRI6
ndash Most devices now support multitouch
bull determine if your device can track distinct points
ndash `Wgt2WR1FR96-F$AltA(gtltXAJA(JgtJX)
37
Input
Other Input
Trackball handling
ndash With I86TB00N8R
bull Unhandled events turn into dpad events
Motion handling
ndash With I8gt8WI6`8C4
bull Must be registered with the gt8WI68C6
bull Disable unneeded sensors especially when paused
ndash Active sensors will quickly drain the battery
38
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
OpenGL
GLSurfaceView
ndash Creates the compatible context
bull Contexts are shared between native code and Dalvik
ndash Creates a rendering thread
ndash Releases the context during onPause
ndash Not the most efficient way to multitask withOpenGL but it avoids some driver issues
When context is lost
ndash Reload resources
bull Textures
bull Buffer objects
bull Shaders
ndash Names donrsquot persist
40
Graphics
Texture Formats
Android encourages innovation in hardware
ndash Chipset vendors use several kinds of proprietary texture compression formats
ndash OpenGL ES supports multiple compressed formats none mandatory
Solutions
ndash Uncompressed Textures
ndash Use ETC1 ndash broad support in 20
bull Optimized around photographic data
bull No Alpha
ndash Use Multi-APK (coming soon)
ndash Put textures on an asset server
bull Detect support at runtime
bull Download to each device
41
Graphics
Drawing for Performance
Draw order is important
ndash Has no impact on some platforms means everything on others
ndash Draw front to back to make best use of early rejects
Use VBOs
ndash Avoid unnecessary state changes
Textures
ndash Use power of 2 sized textures
bull It can be very slow
bull On some chipsets not all address modes work
42
Graphics
Writing Compatible Shaders
Query query
ndash Make sure to query for number of attributes varying and uniforms supported
bull Varies between devices
bull Not respecting will make your application crash
bull ldquoSupportedrdquo does not mean ldquoperforms wellrdquo
Conditions
ndash Avoid as much as possible
bull if necessary put them last in the shader
ndash Use mix() clamp() etc to create the same result
discard()
ndash Avoid discard()
bull if necessary it should be last
43
Graphics
Audio Solutions
Full track audio
s 45amp026
bull Plays multiple formats with codec support
bull Plays from filesystem or from network
bull Has high latency memory and CPU usage for quick sound effects
Sound effects and clips
s gtI984ampII0
bull Plays multiple formats with codec support
bull Preloads audio files to a pool
ndash Plays them with low latency
44
Sound
Audio Solutions
Application-generated audio
s $945I6T
bull Plays PCM audio only with minimal latency
bull Useful for applications that wish to perform sound processing or mixing
OpenSLES
ndash Combines capabilities of 45amp026 and $945I6T
ndash Available only in the NDK
ndash Requires Android 23 and higher
45
Sound
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
Use native AssetManager
ndash Gingerbread and Beyond
Targeting tricky trying tasks
Troubleshooting Tips and Tricks
47
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
One JNI Context Per Thread
Threading Options
49
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
JNI Context 2
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
OR
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
If all else fails Market filters
ndash Instruction set
ndash ARMv5ARMv7
ndash GL version
ndash Platform release
ndash Use Device Availability
Tips Standing Out from the Crowd
Start Small
ndash Download assets as-needed
ndash Hook me early instead of making me wait
Use Android backuprestore service (save to the cloud)
ndash Keep my progress when I switch devices
Support multiple control schemes
ndash Trackball D-pad virtual stick
ndash Let me decide what works best
Support install-to-SD
ndash Android Market users will knock your ratings if you donrsquot
51
Tips Standing Out from the Crowd
Profiling
ndash In-game profiling to select optimal settings per-device
Social
ndash Hook into social networks
ndash Use OpenID
Build a live wallpaper
ndash Own the userrsquos home screen with stats avatars
Analytics
ndash Market and in-game
In-app payments
ndash Consider alternative monetization techniques
52
Troubleshooting Development Tools
NVIDIA Debug Manager for Eclipse
ndash Simplifies setup for native debugger under Eclipse
bull developernvidiacomtegranvidia-debug-manager-android-ndk
WinGDB
ndash Use Visual Studio to debug Android NDK applications
bull wwwwingdbcom
vs-android
ndash Native MSBuild files for Android toolchain
bull vs-androidgooglecodecom
53
Troubleshooting Performance Tools
NVIDIA PerfHUD ES
ndash developernvidiacomtegraperfhud-es
Adreno Profiler
ndash developerqualcommcomshowcaseadreno-profiler
POWERVR Insider Utilities
ndash Including PVRTrace and PVRTune
ndash wwwimgteccompowervrinsiderpowervr-utilitiesasp
54
developerandroidcomsdkndkGoogleGameDevAndroid
Feedback httpgooglNudVs
QampA
55
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
PXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]LPXJ8Na+EIBER+IBEa+E58R+a+E58R+B7+Z
++E0WW+0W++-]LPXJ8N73dGRBER0WW-LPXJ8Na+IBE7U
++E1R`I4J+54++-]LPXJ8N73dGRR`I4J-+++++++++++++++++++++++++++++LPXJ8Na+0Wa+[RTm2N8RW[a+[-n7=[7U
++-]LPXJ8N73d00=I54R`I4-LPXJ8Na+IBEa+54a+PXJltA7U
Development Flow Calling Dalvik Code Within CC++
20
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Build and Deploy
gt=0Alt-amp49BCDBEFG6HI
ndash Builds C libraries and emits so files
gt)-3
ndash (or ant release)
ndash Builds Java classes apk package
gtamp=44
ndash Deploys to emulator or device
21
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdbgdb-rsp over named pipe
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdb
EclipseVS
gdb-rsp over named pipe
gdb-MI
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Important Tip
B)-36amp3)$$)J23
Bringing Your Game to Android
24
Devices Accessing Android Market
25
Android 16
Android 15
Android 23
Android 233
Android 30
Two Week Period Published May 2011
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
NativeActivity is just starting
ndash 43 of checking-in devices can utilize it
ndash For non-tablet-specific titles we can take advantage of NativeActivity without becoming incompatible
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Platform-specific Resources
Using NativeActivity Compatibly
27
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dV0WcQBII0d++++cBII0+81[8IRG58C6B64[dR69cQBII0dcQ6WI96Wd
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dR69cQBII0d++++cBII0+81[8IRG58C6B64[dV0WcQBII0dcQ6WI96Wd
Using NativeActivity Compatibly
28
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
cR5N5R2+846I54)81[Kgt$XR5N$R5N5R2[+++846I54)8B04[^BII0QRWRG58C6B64[d++c1R34R+846I54)81[846I54KLLK05B81[+++++846I54)N09[W8R5N[+Qd++++++++++++++++++++++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6d++++++++++++cQR5N5R2dcR5N5R2+846I54)81[K1I$R5N5R2[+++846I54)8B04[^BII0Q8IRG58C6B64[d++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6dcQR5N5R2d
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+W8R5N$F$Ggt+)+3$XltJXm$gtltFJgt+ )+C09R50WK+k+ LL3846I5438R5NK$JMgt+)+30GgtND+3040+300IC+30G+30846I54$gt$JJMlt$ltJgt+ )+846I548R5NLLC09$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7-00+51LI6R31I490a846I54Q8R5NLLC097
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
LTC+I1KY1L0KW88C0WU
L9B05+0WW+gt$XR5N$R5N5R2+YR84W+846I54KLLKXR5N$R5N5R2+Z
++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
LTC+I1KY1L0KW88C0WU
L9B05+0WW+1I$R5N5R2+YR84W+846I54KLLK$R5N5R2+Z++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++++++gt2WR1K0I45B662-[WE85[7U++++KKK
Key Game Components
33
Lifecycle
Graphics Sound
Input
Assets
Activity LifecycleLifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Process LifecycleLifecycle
Android keeps application processes around for as long as possible
ndash Even when the activity is closed with V585W`-7 or the back key is pressed
The foreground activity process is considered the most important
ndash It can still be killed as a last resort
Visible activities are also given high priority
ndash Backgrounded activities are considered less important
ndash Processes with no active activities are killed first
Implications of the Process LifecycleLifecycle
Be careful with static initializers
ndash Your library cannot be unloaded while your process is active
bull Donrsquot assume that your static initializers will be run when your activity is created
Be careful with threads
ndash Threads are tied to the process not the activity
bull Your threads will continue to run at reduced priority even if your activity is backgrounded or destroyed
ndash Gameplay should stop during onPause
bull It might make sense to keep certain threads running - your activity may still be visible
ndash Make sure all native code is cleaned up during onDestroy
bull Users expect that your application will no longer be active when its activity is destroyed
The Basics
Key handling
ndash Your device most likely has capacitive buttons
bull Look for complete state transitions of I8m2I_8I8m2AL
bull Avoid overriding 45WLR`m2N8R
ndash Use I8m290R5L0I8m2I8Camp6WW
bull Keep your game behaving like an Android application
TouchMultitouch handling
ndash With I8I9`N8R
bull take advantage of built-in gesture processing
ndash use gt0GWR96RRI6 and GWR96RRI6
ndash Most devices now support multitouch
bull determine if your device can track distinct points
ndash `Wgt2WR1FR96-F$AltA(gtltXAJA(JgtJX)
37
Input
Other Input
Trackball handling
ndash With I86TB00N8R
bull Unhandled events turn into dpad events
Motion handling
ndash With I8gt8WI6`8C4
bull Must be registered with the gt8WI68C6
bull Disable unneeded sensors especially when paused
ndash Active sensors will quickly drain the battery
38
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
OpenGL
GLSurfaceView
ndash Creates the compatible context
bull Contexts are shared between native code and Dalvik
ndash Creates a rendering thread
ndash Releases the context during onPause
ndash Not the most efficient way to multitask withOpenGL but it avoids some driver issues
When context is lost
ndash Reload resources
bull Textures
bull Buffer objects
bull Shaders
ndash Names donrsquot persist
40
Graphics
Texture Formats
Android encourages innovation in hardware
ndash Chipset vendors use several kinds of proprietary texture compression formats
ndash OpenGL ES supports multiple compressed formats none mandatory
Solutions
ndash Uncompressed Textures
ndash Use ETC1 ndash broad support in 20
bull Optimized around photographic data
bull No Alpha
ndash Use Multi-APK (coming soon)
ndash Put textures on an asset server
bull Detect support at runtime
bull Download to each device
41
Graphics
Drawing for Performance
Draw order is important
ndash Has no impact on some platforms means everything on others
ndash Draw front to back to make best use of early rejects
Use VBOs
ndash Avoid unnecessary state changes
Textures
ndash Use power of 2 sized textures
bull It can be very slow
bull On some chipsets not all address modes work
42
Graphics
Writing Compatible Shaders
Query query
ndash Make sure to query for number of attributes varying and uniforms supported
bull Varies between devices
bull Not respecting will make your application crash
bull ldquoSupportedrdquo does not mean ldquoperforms wellrdquo
Conditions
ndash Avoid as much as possible
bull if necessary put them last in the shader
ndash Use mix() clamp() etc to create the same result
discard()
ndash Avoid discard()
bull if necessary it should be last
43
Graphics
Audio Solutions
Full track audio
s 45amp026
bull Plays multiple formats with codec support
bull Plays from filesystem or from network
bull Has high latency memory and CPU usage for quick sound effects
Sound effects and clips
s gtI984ampII0
bull Plays multiple formats with codec support
bull Preloads audio files to a pool
ndash Plays them with low latency
44
Sound
Audio Solutions
Application-generated audio
s $945I6T
bull Plays PCM audio only with minimal latency
bull Useful for applications that wish to perform sound processing or mixing
OpenSLES
ndash Combines capabilities of 45amp026 and $945I6T
ndash Available only in the NDK
ndash Requires Android 23 and higher
45
Sound
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
Use native AssetManager
ndash Gingerbread and Beyond
Targeting tricky trying tasks
Troubleshooting Tips and Tricks
47
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
One JNI Context Per Thread
Threading Options
49
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
JNI Context 2
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
OR
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
If all else fails Market filters
ndash Instruction set
ndash ARMv5ARMv7
ndash GL version
ndash Platform release
ndash Use Device Availability
Tips Standing Out from the Crowd
Start Small
ndash Download assets as-needed
ndash Hook me early instead of making me wait
Use Android backuprestore service (save to the cloud)
ndash Keep my progress when I switch devices
Support multiple control schemes
ndash Trackball D-pad virtual stick
ndash Let me decide what works best
Support install-to-SD
ndash Android Market users will knock your ratings if you donrsquot
51
Tips Standing Out from the Crowd
Profiling
ndash In-game profiling to select optimal settings per-device
Social
ndash Hook into social networks
ndash Use OpenID
Build a live wallpaper
ndash Own the userrsquos home screen with stats avatars
Analytics
ndash Market and in-game
In-app payments
ndash Consider alternative monetization techniques
52
Troubleshooting Development Tools
NVIDIA Debug Manager for Eclipse
ndash Simplifies setup for native debugger under Eclipse
bull developernvidiacomtegranvidia-debug-manager-android-ndk
WinGDB
ndash Use Visual Studio to debug Android NDK applications
bull wwwwingdbcom
vs-android
ndash Native MSBuild files for Android toolchain
bull vs-androidgooglecodecom
53
Troubleshooting Performance Tools
NVIDIA PerfHUD ES
ndash developernvidiacomtegraperfhud-es
Adreno Profiler
ndash developerqualcommcomshowcaseadreno-profiler
POWERVR Insider Utilities
ndash Including PVRTrace and PVRTune
ndash wwwimgteccompowervrinsiderpowervr-utilitiesasp
54
developerandroidcomsdkndkGoogleGameDevAndroid
Feedback httpgooglNudVs
QampA
55
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
PXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]LPXJ8Na+EIBER+IBEa+E58R+a+E58R+B7+Z
++E0WW+0W++-]LPXJ8N73dGRBER0WW-LPXJ8Na+IBE7U
++E1R`I4J+54++-]LPXJ8N73dGRR`I4J-+++++++++++++++++++++++++++++LPXJ8Na+0Wa+[RTm2N8RW[a+[-n7=[7U
++-]LPXJ8N73d00=I54R`I4-LPXJ8Na+IBEa+54a+PXJltA7U
Development Flow Calling Dalvik Code Within CC++
20
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Build and Deploy
gt=0Alt-amp49BCDBEFG6HI
ndash Builds C libraries and emits so files
gt)-3
ndash (or ant release)
ndash Builds Java classes apk package
gtamp=44
ndash Deploys to emulator or device
21
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdbgdb-rsp over named pipe
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdb
EclipseVS
gdb-rsp over named pipe
gdb-MI
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Important Tip
B)-36amp3)$$)J23
Bringing Your Game to Android
24
Devices Accessing Android Market
25
Android 16
Android 15
Android 23
Android 233
Android 30
Two Week Period Published May 2011
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
NativeActivity is just starting
ndash 43 of checking-in devices can utilize it
ndash For non-tablet-specific titles we can take advantage of NativeActivity without becoming incompatible
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Platform-specific Resources
Using NativeActivity Compatibly
27
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dV0WcQBII0d++++cBII0+81[8IRG58C6B64[dR69cQBII0dcQ6WI96Wd
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dR69cQBII0d++++cBII0+81[8IRG58C6B64[dV0WcQBII0dcQ6WI96Wd
Using NativeActivity Compatibly
28
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
cR5N5R2+846I54)81[Kgt$XR5N$R5N5R2[+++846I54)8B04[^BII0QRWRG58C6B64[d++c1R34R+846I54)81[846I54KLLK05B81[+++++846I54)N09[W8R5N[+Qd++++++++++++++++++++++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6d++++++++++++cQR5N5R2dcR5N5R2+846I54)81[K1I$R5N5R2[+++846I54)8B04[^BII0Q8IRG58C6B64[d++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6dcQR5N5R2d
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+W8R5N$F$Ggt+)+3$XltJXm$gtltFJgt+ )+C09R50WK+k+ LL3846I5438R5NK$JMgt+)+30GgtND+3040+300IC+30G+30846I54$gt$JJMlt$ltJgt+ )+846I548R5NLLC09$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7-00+51LI6R31I490a846I54Q8R5NLLC097
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
LTC+I1KY1L0KW88C0WU
L9B05+0WW+gt$XR5N$R5N5R2+YR84W+846I54KLLKXR5N$R5N5R2+Z
++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
LTC+I1KY1L0KW88C0WU
L9B05+0WW+1I$R5N5R2+YR84W+846I54KLLK$R5N5R2+Z++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++++++gt2WR1K0I45B662-[WE85[7U++++KKK
Key Game Components
33
Lifecycle
Graphics Sound
Input
Assets
Activity LifecycleLifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Process LifecycleLifecycle
Android keeps application processes around for as long as possible
ndash Even when the activity is closed with V585W`-7 or the back key is pressed
The foreground activity process is considered the most important
ndash It can still be killed as a last resort
Visible activities are also given high priority
ndash Backgrounded activities are considered less important
ndash Processes with no active activities are killed first
Implications of the Process LifecycleLifecycle
Be careful with static initializers
ndash Your library cannot be unloaded while your process is active
bull Donrsquot assume that your static initializers will be run when your activity is created
Be careful with threads
ndash Threads are tied to the process not the activity
bull Your threads will continue to run at reduced priority even if your activity is backgrounded or destroyed
ndash Gameplay should stop during onPause
bull It might make sense to keep certain threads running - your activity may still be visible
ndash Make sure all native code is cleaned up during onDestroy
bull Users expect that your application will no longer be active when its activity is destroyed
The Basics
Key handling
ndash Your device most likely has capacitive buttons
bull Look for complete state transitions of I8m2I_8I8m2AL
bull Avoid overriding 45WLR`m2N8R
ndash Use I8m290R5L0I8m2I8Camp6WW
bull Keep your game behaving like an Android application
TouchMultitouch handling
ndash With I8I9`N8R
bull take advantage of built-in gesture processing
ndash use gt0GWR96RRI6 and GWR96RRI6
ndash Most devices now support multitouch
bull determine if your device can track distinct points
ndash `Wgt2WR1FR96-F$AltA(gtltXAJA(JgtJX)
37
Input
Other Input
Trackball handling
ndash With I86TB00N8R
bull Unhandled events turn into dpad events
Motion handling
ndash With I8gt8WI6`8C4
bull Must be registered with the gt8WI68C6
bull Disable unneeded sensors especially when paused
ndash Active sensors will quickly drain the battery
38
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
OpenGL
GLSurfaceView
ndash Creates the compatible context
bull Contexts are shared between native code and Dalvik
ndash Creates a rendering thread
ndash Releases the context during onPause
ndash Not the most efficient way to multitask withOpenGL but it avoids some driver issues
When context is lost
ndash Reload resources
bull Textures
bull Buffer objects
bull Shaders
ndash Names donrsquot persist
40
Graphics
Texture Formats
Android encourages innovation in hardware
ndash Chipset vendors use several kinds of proprietary texture compression formats
ndash OpenGL ES supports multiple compressed formats none mandatory
Solutions
ndash Uncompressed Textures
ndash Use ETC1 ndash broad support in 20
bull Optimized around photographic data
bull No Alpha
ndash Use Multi-APK (coming soon)
ndash Put textures on an asset server
bull Detect support at runtime
bull Download to each device
41
Graphics
Drawing for Performance
Draw order is important
ndash Has no impact on some platforms means everything on others
ndash Draw front to back to make best use of early rejects
Use VBOs
ndash Avoid unnecessary state changes
Textures
ndash Use power of 2 sized textures
bull It can be very slow
bull On some chipsets not all address modes work
42
Graphics
Writing Compatible Shaders
Query query
ndash Make sure to query for number of attributes varying and uniforms supported
bull Varies between devices
bull Not respecting will make your application crash
bull ldquoSupportedrdquo does not mean ldquoperforms wellrdquo
Conditions
ndash Avoid as much as possible
bull if necessary put them last in the shader
ndash Use mix() clamp() etc to create the same result
discard()
ndash Avoid discard()
bull if necessary it should be last
43
Graphics
Audio Solutions
Full track audio
s 45amp026
bull Plays multiple formats with codec support
bull Plays from filesystem or from network
bull Has high latency memory and CPU usage for quick sound effects
Sound effects and clips
s gtI984ampII0
bull Plays multiple formats with codec support
bull Preloads audio files to a pool
ndash Plays them with low latency
44
Sound
Audio Solutions
Application-generated audio
s $945I6T
bull Plays PCM audio only with minimal latency
bull Useful for applications that wish to perform sound processing or mixing
OpenSLES
ndash Combines capabilities of 45amp026 and $945I6T
ndash Available only in the NDK
ndash Requires Android 23 and higher
45
Sound
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
Use native AssetManager
ndash Gingerbread and Beyond
Targeting tricky trying tasks
Troubleshooting Tips and Tricks
47
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
One JNI Context Per Thread
Threading Options
49
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
JNI Context 2
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
OR
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
If all else fails Market filters
ndash Instruction set
ndash ARMv5ARMv7
ndash GL version
ndash Platform release
ndash Use Device Availability
Tips Standing Out from the Crowd
Start Small
ndash Download assets as-needed
ndash Hook me early instead of making me wait
Use Android backuprestore service (save to the cloud)
ndash Keep my progress when I switch devices
Support multiple control schemes
ndash Trackball D-pad virtual stick
ndash Let me decide what works best
Support install-to-SD
ndash Android Market users will knock your ratings if you donrsquot
51
Tips Standing Out from the Crowd
Profiling
ndash In-game profiling to select optimal settings per-device
Social
ndash Hook into social networks
ndash Use OpenID
Build a live wallpaper
ndash Own the userrsquos home screen with stats avatars
Analytics
ndash Market and in-game
In-app payments
ndash Consider alternative monetization techniques
52
Troubleshooting Development Tools
NVIDIA Debug Manager for Eclipse
ndash Simplifies setup for native debugger under Eclipse
bull developernvidiacomtegranvidia-debug-manager-android-ndk
WinGDB
ndash Use Visual Studio to debug Android NDK applications
bull wwwwingdbcom
vs-android
ndash Native MSBuild files for Android toolchain
bull vs-androidgooglecodecom
53
Troubleshooting Performance Tools
NVIDIA PerfHUD ES
ndash developernvidiacomtegraperfhud-es
Adreno Profiler
ndash developerqualcommcomshowcaseadreno-profiler
POWERVR Insider Utilities
ndash Including PVRTrace and PVRTune
ndash wwwimgteccompowervrinsiderpowervr-utilitiesasp
54
developerandroidcomsdkndkGoogleGameDevAndroid
Feedback httpgooglNudVs
QampA
55
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
PXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]LPXJ8Na+EIBER+IBEa+E58R+a+E58R+B7+Z
++E0WW+0W++-]LPXJ8N73dGRBER0WW-LPXJ8Na+IBE7U
++E1R`I4J+54++-]LPXJ8N73dGRR`I4J-+++++++++++++++++++++++++++++LPXJ8Na+0Wa+[RTm2N8RW[a+[-n7=[7U
++-]LPXJ8N73d00=I54R`I4-LPXJ8Na+IBEa+54a+PXJltA7U
Development Flow Calling Dalvik Code Within CC++
20
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Build and Deploy
gt=0Alt-amp49BCDBEFG6HI
ndash Builds C libraries and emits so files
gt)-3
ndash (or ant release)
ndash Builds Java classes apk package
gtamp=44
ndash Deploys to emulator or device
21
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdbgdb-rsp over named pipe
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdb
EclipseVS
gdb-rsp over named pipe
gdb-MI
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Important Tip
B)-36amp3)$$)J23
Bringing Your Game to Android
24
Devices Accessing Android Market
25
Android 16
Android 15
Android 23
Android 233
Android 30
Two Week Period Published May 2011
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
NativeActivity is just starting
ndash 43 of checking-in devices can utilize it
ndash For non-tablet-specific titles we can take advantage of NativeActivity without becoming incompatible
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Platform-specific Resources
Using NativeActivity Compatibly
27
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dV0WcQBII0d++++cBII0+81[8IRG58C6B64[dR69cQBII0dcQ6WI96Wd
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dR69cQBII0d++++cBII0+81[8IRG58C6B64[dV0WcQBII0dcQ6WI96Wd
Using NativeActivity Compatibly
28
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
cR5N5R2+846I54)81[Kgt$XR5N$R5N5R2[+++846I54)8B04[^BII0QRWRG58C6B64[d++c1R34R+846I54)81[846I54KLLK05B81[+++++846I54)N09[W8R5N[+Qd++++++++++++++++++++++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6d++++++++++++cQR5N5R2dcR5N5R2+846I54)81[K1I$R5N5R2[+++846I54)8B04[^BII0Q8IRG58C6B64[d++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6dcQR5N5R2d
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+W8R5N$F$Ggt+)+3$XltJXm$gtltFJgt+ )+C09R50WK+k+ LL3846I5438R5NK$JMgt+)+30GgtND+3040+300IC+30G+30846I54$gt$JJMlt$ltJgt+ )+846I548R5NLLC09$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7-00+51LI6R31I490a846I54Q8R5NLLC097
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
LTC+I1KY1L0KW88C0WU
L9B05+0WW+gt$XR5N$R5N5R2+YR84W+846I54KLLKXR5N$R5N5R2+Z
++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
LTC+I1KY1L0KW88C0WU
L9B05+0WW+1I$R5N5R2+YR84W+846I54KLLK$R5N5R2+Z++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++++++gt2WR1K0I45B662-[WE85[7U++++KKK
Key Game Components
33
Lifecycle
Graphics Sound
Input
Assets
Activity LifecycleLifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Process LifecycleLifecycle
Android keeps application processes around for as long as possible
ndash Even when the activity is closed with V585W`-7 or the back key is pressed
The foreground activity process is considered the most important
ndash It can still be killed as a last resort
Visible activities are also given high priority
ndash Backgrounded activities are considered less important
ndash Processes with no active activities are killed first
Implications of the Process LifecycleLifecycle
Be careful with static initializers
ndash Your library cannot be unloaded while your process is active
bull Donrsquot assume that your static initializers will be run when your activity is created
Be careful with threads
ndash Threads are tied to the process not the activity
bull Your threads will continue to run at reduced priority even if your activity is backgrounded or destroyed
ndash Gameplay should stop during onPause
bull It might make sense to keep certain threads running - your activity may still be visible
ndash Make sure all native code is cleaned up during onDestroy
bull Users expect that your application will no longer be active when its activity is destroyed
The Basics
Key handling
ndash Your device most likely has capacitive buttons
bull Look for complete state transitions of I8m2I_8I8m2AL
bull Avoid overriding 45WLR`m2N8R
ndash Use I8m290R5L0I8m2I8Camp6WW
bull Keep your game behaving like an Android application
TouchMultitouch handling
ndash With I8I9`N8R
bull take advantage of built-in gesture processing
ndash use gt0GWR96RRI6 and GWR96RRI6
ndash Most devices now support multitouch
bull determine if your device can track distinct points
ndash `Wgt2WR1FR96-F$AltA(gtltXAJA(JgtJX)
37
Input
Other Input
Trackball handling
ndash With I86TB00N8R
bull Unhandled events turn into dpad events
Motion handling
ndash With I8gt8WI6`8C4
bull Must be registered with the gt8WI68C6
bull Disable unneeded sensors especially when paused
ndash Active sensors will quickly drain the battery
38
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
OpenGL
GLSurfaceView
ndash Creates the compatible context
bull Contexts are shared between native code and Dalvik
ndash Creates a rendering thread
ndash Releases the context during onPause
ndash Not the most efficient way to multitask withOpenGL but it avoids some driver issues
When context is lost
ndash Reload resources
bull Textures
bull Buffer objects
bull Shaders
ndash Names donrsquot persist
40
Graphics
Texture Formats
Android encourages innovation in hardware
ndash Chipset vendors use several kinds of proprietary texture compression formats
ndash OpenGL ES supports multiple compressed formats none mandatory
Solutions
ndash Uncompressed Textures
ndash Use ETC1 ndash broad support in 20
bull Optimized around photographic data
bull No Alpha
ndash Use Multi-APK (coming soon)
ndash Put textures on an asset server
bull Detect support at runtime
bull Download to each device
41
Graphics
Drawing for Performance
Draw order is important
ndash Has no impact on some platforms means everything on others
ndash Draw front to back to make best use of early rejects
Use VBOs
ndash Avoid unnecessary state changes
Textures
ndash Use power of 2 sized textures
bull It can be very slow
bull On some chipsets not all address modes work
42
Graphics
Writing Compatible Shaders
Query query
ndash Make sure to query for number of attributes varying and uniforms supported
bull Varies between devices
bull Not respecting will make your application crash
bull ldquoSupportedrdquo does not mean ldquoperforms wellrdquo
Conditions
ndash Avoid as much as possible
bull if necessary put them last in the shader
ndash Use mix() clamp() etc to create the same result
discard()
ndash Avoid discard()
bull if necessary it should be last
43
Graphics
Audio Solutions
Full track audio
s 45amp026
bull Plays multiple formats with codec support
bull Plays from filesystem or from network
bull Has high latency memory and CPU usage for quick sound effects
Sound effects and clips
s gtI984ampII0
bull Plays multiple formats with codec support
bull Preloads audio files to a pool
ndash Plays them with low latency
44
Sound
Audio Solutions
Application-generated audio
s $945I6T
bull Plays PCM audio only with minimal latency
bull Useful for applications that wish to perform sound processing or mixing
OpenSLES
ndash Combines capabilities of 45amp026 and $945I6T
ndash Available only in the NDK
ndash Requires Android 23 and higher
45
Sound
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
Use native AssetManager
ndash Gingerbread and Beyond
Targeting tricky trying tasks
Troubleshooting Tips and Tricks
47
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
One JNI Context Per Thread
Threading Options
49
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
JNI Context 2
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
OR
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
If all else fails Market filters
ndash Instruction set
ndash ARMv5ARMv7
ndash GL version
ndash Platform release
ndash Use Device Availability
Tips Standing Out from the Crowd
Start Small
ndash Download assets as-needed
ndash Hook me early instead of making me wait
Use Android backuprestore service (save to the cloud)
ndash Keep my progress when I switch devices
Support multiple control schemes
ndash Trackball D-pad virtual stick
ndash Let me decide what works best
Support install-to-SD
ndash Android Market users will knock your ratings if you donrsquot
51
Tips Standing Out from the Crowd
Profiling
ndash In-game profiling to select optimal settings per-device
Social
ndash Hook into social networks
ndash Use OpenID
Build a live wallpaper
ndash Own the userrsquos home screen with stats avatars
Analytics
ndash Market and in-game
In-app payments
ndash Consider alternative monetization techniques
52
Troubleshooting Development Tools
NVIDIA Debug Manager for Eclipse
ndash Simplifies setup for native debugger under Eclipse
bull developernvidiacomtegranvidia-debug-manager-android-ndk
WinGDB
ndash Use Visual Studio to debug Android NDK applications
bull wwwwingdbcom
vs-android
ndash Native MSBuild files for Android toolchain
bull vs-androidgooglecodecom
53
Troubleshooting Performance Tools
NVIDIA PerfHUD ES
ndash developernvidiacomtegraperfhud-es
Adreno Profiler
ndash developerqualcommcomshowcaseadreno-profiler
POWERVR Insider Utilities
ndash Including PVRTrace and PVRTune
ndash wwwimgteccompowervrinsiderpowervr-utilitiesasp
54
developerandroidcomsdkndkGoogleGameDevAndroid
Feedback httpgooglNudVs
QampA
55
Generate with javah tool 0(12$amp2345amp2675897amp
bull Eclipse Source|Generate C files from Java class
L9B05+8R5N+NI54+585R-58R+_54R`a+58R+`5C`R7UL9B05+WRR5+8R5N+NI54+WRL-7U
b58094+cE85K`dQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++585R++++gt5C8R96)+-JJ7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]a+EIBERa+E58Ra+E58R7UQ]+]+0WW)+++++I1846I54C0DE85GDPXJ5B+]+R`I4)++++WRL++++gt5C8R96)+-7=+]QPXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5BWRL++-PXJ8N+]a+E0WW7U
Development Flow JNI Glue
18
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
PXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]LPXJ8Na+EIBER+IBEa+E58R+a+E58R+B7+Z
++E0WW+0W++-]LPXJ8N73dGRBER0WW-LPXJ8Na+IBE7U
++E1R`I4J+54++-]LPXJ8N73dGRR`I4J-+++++++++++++++++++++++++++++LPXJ8Na+0Wa+[RTm2N8RW[a+[-n7=[7U
++-]LPXJ8N73d00=I54R`I4-LPXJ8Na+IBEa+54a+PXJltA7U
Development Flow Calling Dalvik Code Within CC++
20
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Build and Deploy
gt=0Alt-amp49BCDBEFG6HI
ndash Builds C libraries and emits so files
gt)-3
ndash (or ant release)
ndash Builds Java classes apk package
gtamp=44
ndash Deploys to emulator or device
21
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdbgdb-rsp over named pipe
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdb
EclipseVS
gdb-rsp over named pipe
gdb-MI
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Important Tip
B)-36amp3)$$)J23
Bringing Your Game to Android
24
Devices Accessing Android Market
25
Android 16
Android 15
Android 23
Android 233
Android 30
Two Week Period Published May 2011
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
NativeActivity is just starting
ndash 43 of checking-in devices can utilize it
ndash For non-tablet-specific titles we can take advantage of NativeActivity without becoming incompatible
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Platform-specific Resources
Using NativeActivity Compatibly
27
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dV0WcQBII0d++++cBII0+81[8IRG58C6B64[dR69cQBII0dcQ6WI96Wd
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dR69cQBII0d++++cBII0+81[8IRG58C6B64[dV0WcQBII0dcQ6WI96Wd
Using NativeActivity Compatibly
28
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
cR5N5R2+846I54)81[Kgt$XR5N$R5N5R2[+++846I54)8B04[^BII0QRWRG58C6B64[d++c1R34R+846I54)81[846I54KLLK05B81[+++++846I54)N09[W8R5N[+Qd++++++++++++++++++++++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6d++++++++++++cQR5N5R2dcR5N5R2+846I54)81[K1I$R5N5R2[+++846I54)8B04[^BII0Q8IRG58C6B64[d++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6dcQR5N5R2d
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+W8R5N$F$Ggt+)+3$XltJXm$gtltFJgt+ )+C09R50WK+k+ LL3846I5438R5NK$JMgt+)+30GgtND+3040+300IC+30G+30846I54$gt$JJMlt$ltJgt+ )+846I548R5NLLC09$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7-00+51LI6R31I490a846I54Q8R5NLLC097
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
LTC+I1KY1L0KW88C0WU
L9B05+0WW+gt$XR5N$R5N5R2+YR84W+846I54KLLKXR5N$R5N5R2+Z
++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
LTC+I1KY1L0KW88C0WU
L9B05+0WW+1I$R5N5R2+YR84W+846I54KLLK$R5N5R2+Z++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++++++gt2WR1K0I45B662-[WE85[7U++++KKK
Key Game Components
33
Lifecycle
Graphics Sound
Input
Assets
Activity LifecycleLifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Process LifecycleLifecycle
Android keeps application processes around for as long as possible
ndash Even when the activity is closed with V585W`-7 or the back key is pressed
The foreground activity process is considered the most important
ndash It can still be killed as a last resort
Visible activities are also given high priority
ndash Backgrounded activities are considered less important
ndash Processes with no active activities are killed first
Implications of the Process LifecycleLifecycle
Be careful with static initializers
ndash Your library cannot be unloaded while your process is active
bull Donrsquot assume that your static initializers will be run when your activity is created
Be careful with threads
ndash Threads are tied to the process not the activity
bull Your threads will continue to run at reduced priority even if your activity is backgrounded or destroyed
ndash Gameplay should stop during onPause
bull It might make sense to keep certain threads running - your activity may still be visible
ndash Make sure all native code is cleaned up during onDestroy
bull Users expect that your application will no longer be active when its activity is destroyed
The Basics
Key handling
ndash Your device most likely has capacitive buttons
bull Look for complete state transitions of I8m2I_8I8m2AL
bull Avoid overriding 45WLR`m2N8R
ndash Use I8m290R5L0I8m2I8Camp6WW
bull Keep your game behaving like an Android application
TouchMultitouch handling
ndash With I8I9`N8R
bull take advantage of built-in gesture processing
ndash use gt0GWR96RRI6 and GWR96RRI6
ndash Most devices now support multitouch
bull determine if your device can track distinct points
ndash `Wgt2WR1FR96-F$AltA(gtltXAJA(JgtJX)
37
Input
Other Input
Trackball handling
ndash With I86TB00N8R
bull Unhandled events turn into dpad events
Motion handling
ndash With I8gt8WI6`8C4
bull Must be registered with the gt8WI68C6
bull Disable unneeded sensors especially when paused
ndash Active sensors will quickly drain the battery
38
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
OpenGL
GLSurfaceView
ndash Creates the compatible context
bull Contexts are shared between native code and Dalvik
ndash Creates a rendering thread
ndash Releases the context during onPause
ndash Not the most efficient way to multitask withOpenGL but it avoids some driver issues
When context is lost
ndash Reload resources
bull Textures
bull Buffer objects
bull Shaders
ndash Names donrsquot persist
40
Graphics
Texture Formats
Android encourages innovation in hardware
ndash Chipset vendors use several kinds of proprietary texture compression formats
ndash OpenGL ES supports multiple compressed formats none mandatory
Solutions
ndash Uncompressed Textures
ndash Use ETC1 ndash broad support in 20
bull Optimized around photographic data
bull No Alpha
ndash Use Multi-APK (coming soon)
ndash Put textures on an asset server
bull Detect support at runtime
bull Download to each device
41
Graphics
Drawing for Performance
Draw order is important
ndash Has no impact on some platforms means everything on others
ndash Draw front to back to make best use of early rejects
Use VBOs
ndash Avoid unnecessary state changes
Textures
ndash Use power of 2 sized textures
bull It can be very slow
bull On some chipsets not all address modes work
42
Graphics
Writing Compatible Shaders
Query query
ndash Make sure to query for number of attributes varying and uniforms supported
bull Varies between devices
bull Not respecting will make your application crash
bull ldquoSupportedrdquo does not mean ldquoperforms wellrdquo
Conditions
ndash Avoid as much as possible
bull if necessary put them last in the shader
ndash Use mix() clamp() etc to create the same result
discard()
ndash Avoid discard()
bull if necessary it should be last
43
Graphics
Audio Solutions
Full track audio
s 45amp026
bull Plays multiple formats with codec support
bull Plays from filesystem or from network
bull Has high latency memory and CPU usage for quick sound effects
Sound effects and clips
s gtI984ampII0
bull Plays multiple formats with codec support
bull Preloads audio files to a pool
ndash Plays them with low latency
44
Sound
Audio Solutions
Application-generated audio
s $945I6T
bull Plays PCM audio only with minimal latency
bull Useful for applications that wish to perform sound processing or mixing
OpenSLES
ndash Combines capabilities of 45amp026 and $945I6T
ndash Available only in the NDK
ndash Requires Android 23 and higher
45
Sound
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
Use native AssetManager
ndash Gingerbread and Beyond
Targeting tricky trying tasks
Troubleshooting Tips and Tricks
47
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
One JNI Context Per Thread
Threading Options
49
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
JNI Context 2
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
OR
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
If all else fails Market filters
ndash Instruction set
ndash ARMv5ARMv7
ndash GL version
ndash Platform release
ndash Use Device Availability
Tips Standing Out from the Crowd
Start Small
ndash Download assets as-needed
ndash Hook me early instead of making me wait
Use Android backuprestore service (save to the cloud)
ndash Keep my progress when I switch devices
Support multiple control schemes
ndash Trackball D-pad virtual stick
ndash Let me decide what works best
Support install-to-SD
ndash Android Market users will knock your ratings if you donrsquot
51
Tips Standing Out from the Crowd
Profiling
ndash In-game profiling to select optimal settings per-device
Social
ndash Hook into social networks
ndash Use OpenID
Build a live wallpaper
ndash Own the userrsquos home screen with stats avatars
Analytics
ndash Market and in-game
In-app payments
ndash Consider alternative monetization techniques
52
Troubleshooting Development Tools
NVIDIA Debug Manager for Eclipse
ndash Simplifies setup for native debugger under Eclipse
bull developernvidiacomtegranvidia-debug-manager-android-ndk
WinGDB
ndash Use Visual Studio to debug Android NDK applications
bull wwwwingdbcom
vs-android
ndash Native MSBuild files for Android toolchain
bull vs-androidgooglecodecom
53
Troubleshooting Performance Tools
NVIDIA PerfHUD ES
ndash developernvidiacomtegraperfhud-es
Adreno Profiler
ndash developerqualcommcomshowcaseadreno-profiler
POWERVR Insider Utilities
ndash Including PVRTrace and PVRTune
ndash wwwimgteccompowervrinsiderpowervr-utilitiesasp
54
developerandroidcomsdkndkGoogleGameDevAndroid
Feedback httpgooglNudVs
QampA
55
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
PXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]LPXJ8Na+EIBER+IBEa+E58R+a+E58R+B7+Z
++E0WW+0W++-]LPXJ8N73dGRBER0WW-LPXJ8Na+IBE7U
++E1R`I4J+54++-]LPXJ8N73dGRR`I4J-+++++++++++++++++++++++++++++LPXJ8Na+0Wa+[RTm2N8RW[a+[-n7=[7U
++-]LPXJ8N73d00=I54R`I4-LPXJ8Na+IBEa+54a+PXJltA7U
Development Flow Calling Dalvik Code Within CC++
20
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Build and Deploy
gt=0Alt-amp49BCDBEFG6HI
ndash Builds C libraries and emits so files
gt)-3
ndash (or ant release)
ndash Builds Java classes apk package
gtamp=44
ndash Deploys to emulator or device
21
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdbgdb-rsp over named pipe
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdb
EclipseVS
gdb-rsp over named pipe
gdb-MI
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Important Tip
B)-36amp3)$$)J23
Bringing Your Game to Android
24
Devices Accessing Android Market
25
Android 16
Android 15
Android 23
Android 233
Android 30
Two Week Period Published May 2011
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
NativeActivity is just starting
ndash 43 of checking-in devices can utilize it
ndash For non-tablet-specific titles we can take advantage of NativeActivity without becoming incompatible
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Platform-specific Resources
Using NativeActivity Compatibly
27
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dV0WcQBII0d++++cBII0+81[8IRG58C6B64[dR69cQBII0dcQ6WI96Wd
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dR69cQBII0d++++cBII0+81[8IRG58C6B64[dV0WcQBII0dcQ6WI96Wd
Using NativeActivity Compatibly
28
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
cR5N5R2+846I54)81[Kgt$XR5N$R5N5R2[+++846I54)8B04[^BII0QRWRG58C6B64[d++c1R34R+846I54)81[846I54KLLK05B81[+++++846I54)N09[W8R5N[+Qd++++++++++++++++++++++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6d++++++++++++cQR5N5R2dcR5N5R2+846I54)81[K1I$R5N5R2[+++846I54)8B04[^BII0Q8IRG58C6B64[d++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6dcQR5N5R2d
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+W8R5N$F$Ggt+)+3$XltJXm$gtltFJgt+ )+C09R50WK+k+ LL3846I5438R5NK$JMgt+)+30GgtND+3040+300IC+30G+30846I54$gt$JJMlt$ltJgt+ )+846I548R5NLLC09$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7-00+51LI6R31I490a846I54Q8R5NLLC097
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
LTC+I1KY1L0KW88C0WU
L9B05+0WW+gt$XR5N$R5N5R2+YR84W+846I54KLLKXR5N$R5N5R2+Z
++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
LTC+I1KY1L0KW88C0WU
L9B05+0WW+1I$R5N5R2+YR84W+846I54KLLK$R5N5R2+Z++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++++++gt2WR1K0I45B662-[WE85[7U++++KKK
Key Game Components
33
Lifecycle
Graphics Sound
Input
Assets
Activity LifecycleLifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Process LifecycleLifecycle
Android keeps application processes around for as long as possible
ndash Even when the activity is closed with V585W`-7 or the back key is pressed
The foreground activity process is considered the most important
ndash It can still be killed as a last resort
Visible activities are also given high priority
ndash Backgrounded activities are considered less important
ndash Processes with no active activities are killed first
Implications of the Process LifecycleLifecycle
Be careful with static initializers
ndash Your library cannot be unloaded while your process is active
bull Donrsquot assume that your static initializers will be run when your activity is created
Be careful with threads
ndash Threads are tied to the process not the activity
bull Your threads will continue to run at reduced priority even if your activity is backgrounded or destroyed
ndash Gameplay should stop during onPause
bull It might make sense to keep certain threads running - your activity may still be visible
ndash Make sure all native code is cleaned up during onDestroy
bull Users expect that your application will no longer be active when its activity is destroyed
The Basics
Key handling
ndash Your device most likely has capacitive buttons
bull Look for complete state transitions of I8m2I_8I8m2AL
bull Avoid overriding 45WLR`m2N8R
ndash Use I8m290R5L0I8m2I8Camp6WW
bull Keep your game behaving like an Android application
TouchMultitouch handling
ndash With I8I9`N8R
bull take advantage of built-in gesture processing
ndash use gt0GWR96RRI6 and GWR96RRI6
ndash Most devices now support multitouch
bull determine if your device can track distinct points
ndash `Wgt2WR1FR96-F$AltA(gtltXAJA(JgtJX)
37
Input
Other Input
Trackball handling
ndash With I86TB00N8R
bull Unhandled events turn into dpad events
Motion handling
ndash With I8gt8WI6`8C4
bull Must be registered with the gt8WI68C6
bull Disable unneeded sensors especially when paused
ndash Active sensors will quickly drain the battery
38
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
OpenGL
GLSurfaceView
ndash Creates the compatible context
bull Contexts are shared between native code and Dalvik
ndash Creates a rendering thread
ndash Releases the context during onPause
ndash Not the most efficient way to multitask withOpenGL but it avoids some driver issues
When context is lost
ndash Reload resources
bull Textures
bull Buffer objects
bull Shaders
ndash Names donrsquot persist
40
Graphics
Texture Formats
Android encourages innovation in hardware
ndash Chipset vendors use several kinds of proprietary texture compression formats
ndash OpenGL ES supports multiple compressed formats none mandatory
Solutions
ndash Uncompressed Textures
ndash Use ETC1 ndash broad support in 20
bull Optimized around photographic data
bull No Alpha
ndash Use Multi-APK (coming soon)
ndash Put textures on an asset server
bull Detect support at runtime
bull Download to each device
41
Graphics
Drawing for Performance
Draw order is important
ndash Has no impact on some platforms means everything on others
ndash Draw front to back to make best use of early rejects
Use VBOs
ndash Avoid unnecessary state changes
Textures
ndash Use power of 2 sized textures
bull It can be very slow
bull On some chipsets not all address modes work
42
Graphics
Writing Compatible Shaders
Query query
ndash Make sure to query for number of attributes varying and uniforms supported
bull Varies between devices
bull Not respecting will make your application crash
bull ldquoSupportedrdquo does not mean ldquoperforms wellrdquo
Conditions
ndash Avoid as much as possible
bull if necessary put them last in the shader
ndash Use mix() clamp() etc to create the same result
discard()
ndash Avoid discard()
bull if necessary it should be last
43
Graphics
Audio Solutions
Full track audio
s 45amp026
bull Plays multiple formats with codec support
bull Plays from filesystem or from network
bull Has high latency memory and CPU usage for quick sound effects
Sound effects and clips
s gtI984ampII0
bull Plays multiple formats with codec support
bull Preloads audio files to a pool
ndash Plays them with low latency
44
Sound
Audio Solutions
Application-generated audio
s $945I6T
bull Plays PCM audio only with minimal latency
bull Useful for applications that wish to perform sound processing or mixing
OpenSLES
ndash Combines capabilities of 45amp026 and $945I6T
ndash Available only in the NDK
ndash Requires Android 23 and higher
45
Sound
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
Use native AssetManager
ndash Gingerbread and Beyond
Targeting tricky trying tasks
Troubleshooting Tips and Tricks
47
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
One JNI Context Per Thread
Threading Options
49
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
JNI Context 2
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
OR
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
If all else fails Market filters
ndash Instruction set
ndash ARMv5ARMv7
ndash GL version
ndash Platform release
ndash Use Device Availability
Tips Standing Out from the Crowd
Start Small
ndash Download assets as-needed
ndash Hook me early instead of making me wait
Use Android backuprestore service (save to the cloud)
ndash Keep my progress when I switch devices
Support multiple control schemes
ndash Trackball D-pad virtual stick
ndash Let me decide what works best
Support install-to-SD
ndash Android Market users will knock your ratings if you donrsquot
51
Tips Standing Out from the Crowd
Profiling
ndash In-game profiling to select optimal settings per-device
Social
ndash Hook into social networks
ndash Use OpenID
Build a live wallpaper
ndash Own the userrsquos home screen with stats avatars
Analytics
ndash Market and in-game
In-app payments
ndash Consider alternative monetization techniques
52
Troubleshooting Development Tools
NVIDIA Debug Manager for Eclipse
ndash Simplifies setup for native debugger under Eclipse
bull developernvidiacomtegranvidia-debug-manager-android-ndk
WinGDB
ndash Use Visual Studio to debug Android NDK applications
bull wwwwingdbcom
vs-android
ndash Native MSBuild files for Android toolchain
bull vs-androidgooglecodecom
53
Troubleshooting Performance Tools
NVIDIA PerfHUD ES
ndash developernvidiacomtegraperfhud-es
Adreno Profiler
ndash developerqualcommcomshowcaseadreno-profiler
POWERVR Insider Utilities
ndash Including PVRTrace and PVRTune
ndash wwwimgteccompowervrinsiderpowervr-utilitiesasp
54
developerandroidcomsdkndkGoogleGameDevAndroid
Feedback httpgooglNudVs
QampA
55
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
PXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]LPXJ8Na+EIBER+IBEa+E58R+a+E58R+B7+Z
++E0WW+0W++-]LPXJ8N73dGRBER0WW-LPXJ8Na+IBE7U
++E1R`I4J+54++-]LPXJ8N73dGRR`I4J-+++++++++++++++++++++++++++++LPXJ8Na+0Wa+[RTm2N8RW[a+[-n7=[7U
++-]LPXJ8N73d00=I54R`I4-LPXJ8Na+IBEa+54a+PXJltA7U
Development Flow Calling Dalvik Code Within CC++
20
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Build and Deploy
gt=0Alt-amp49BCDBEFG6HI
ndash Builds C libraries and emits so files
gt)-3
ndash (or ant release)
ndash Builds Java classes apk package
gtamp=44
ndash Deploys to emulator or device
21
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdbgdb-rsp over named pipe
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdb
EclipseVS
gdb-rsp over named pipe
gdb-MI
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Important Tip
B)-36amp3)$$)J23
Bringing Your Game to Android
24
Devices Accessing Android Market
25
Android 16
Android 15
Android 23
Android 233
Android 30
Two Week Period Published May 2011
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
NativeActivity is just starting
ndash 43 of checking-in devices can utilize it
ndash For non-tablet-specific titles we can take advantage of NativeActivity without becoming incompatible
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Platform-specific Resources
Using NativeActivity Compatibly
27
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dV0WcQBII0d++++cBII0+81[8IRG58C6B64[dR69cQBII0dcQ6WI96Wd
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dR69cQBII0d++++cBII0+81[8IRG58C6B64[dV0WcQBII0dcQ6WI96Wd
Using NativeActivity Compatibly
28
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
cR5N5R2+846I54)81[Kgt$XR5N$R5N5R2[+++846I54)8B04[^BII0QRWRG58C6B64[d++c1R34R+846I54)81[846I54KLLK05B81[+++++846I54)N09[W8R5N[+Qd++++++++++++++++++++++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6d++++++++++++cQR5N5R2dcR5N5R2+846I54)81[K1I$R5N5R2[+++846I54)8B04[^BII0Q8IRG58C6B64[d++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6dcQR5N5R2d
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+W8R5N$F$Ggt+)+3$XltJXm$gtltFJgt+ )+C09R50WK+k+ LL3846I5438R5NK$JMgt+)+30GgtND+3040+300IC+30G+30846I54$gt$JJMlt$ltJgt+ )+846I548R5NLLC09$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7-00+51LI6R31I490a846I54Q8R5NLLC097
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
LTC+I1KY1L0KW88C0WU
L9B05+0WW+gt$XR5N$R5N5R2+YR84W+846I54KLLKXR5N$R5N5R2+Z
++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
LTC+I1KY1L0KW88C0WU
L9B05+0WW+1I$R5N5R2+YR84W+846I54KLLK$R5N5R2+Z++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++++++gt2WR1K0I45B662-[WE85[7U++++KKK
Key Game Components
33
Lifecycle
Graphics Sound
Input
Assets
Activity LifecycleLifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Process LifecycleLifecycle
Android keeps application processes around for as long as possible
ndash Even when the activity is closed with V585W`-7 or the back key is pressed
The foreground activity process is considered the most important
ndash It can still be killed as a last resort
Visible activities are also given high priority
ndash Backgrounded activities are considered less important
ndash Processes with no active activities are killed first
Implications of the Process LifecycleLifecycle
Be careful with static initializers
ndash Your library cannot be unloaded while your process is active
bull Donrsquot assume that your static initializers will be run when your activity is created
Be careful with threads
ndash Threads are tied to the process not the activity
bull Your threads will continue to run at reduced priority even if your activity is backgrounded or destroyed
ndash Gameplay should stop during onPause
bull It might make sense to keep certain threads running - your activity may still be visible
ndash Make sure all native code is cleaned up during onDestroy
bull Users expect that your application will no longer be active when its activity is destroyed
The Basics
Key handling
ndash Your device most likely has capacitive buttons
bull Look for complete state transitions of I8m2I_8I8m2AL
bull Avoid overriding 45WLR`m2N8R
ndash Use I8m290R5L0I8m2I8Camp6WW
bull Keep your game behaving like an Android application
TouchMultitouch handling
ndash With I8I9`N8R
bull take advantage of built-in gesture processing
ndash use gt0GWR96RRI6 and GWR96RRI6
ndash Most devices now support multitouch
bull determine if your device can track distinct points
ndash `Wgt2WR1FR96-F$AltA(gtltXAJA(JgtJX)
37
Input
Other Input
Trackball handling
ndash With I86TB00N8R
bull Unhandled events turn into dpad events
Motion handling
ndash With I8gt8WI6`8C4
bull Must be registered with the gt8WI68C6
bull Disable unneeded sensors especially when paused
ndash Active sensors will quickly drain the battery
38
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
OpenGL
GLSurfaceView
ndash Creates the compatible context
bull Contexts are shared between native code and Dalvik
ndash Creates a rendering thread
ndash Releases the context during onPause
ndash Not the most efficient way to multitask withOpenGL but it avoids some driver issues
When context is lost
ndash Reload resources
bull Textures
bull Buffer objects
bull Shaders
ndash Names donrsquot persist
40
Graphics
Texture Formats
Android encourages innovation in hardware
ndash Chipset vendors use several kinds of proprietary texture compression formats
ndash OpenGL ES supports multiple compressed formats none mandatory
Solutions
ndash Uncompressed Textures
ndash Use ETC1 ndash broad support in 20
bull Optimized around photographic data
bull No Alpha
ndash Use Multi-APK (coming soon)
ndash Put textures on an asset server
bull Detect support at runtime
bull Download to each device
41
Graphics
Drawing for Performance
Draw order is important
ndash Has no impact on some platforms means everything on others
ndash Draw front to back to make best use of early rejects
Use VBOs
ndash Avoid unnecessary state changes
Textures
ndash Use power of 2 sized textures
bull It can be very slow
bull On some chipsets not all address modes work
42
Graphics
Writing Compatible Shaders
Query query
ndash Make sure to query for number of attributes varying and uniforms supported
bull Varies between devices
bull Not respecting will make your application crash
bull ldquoSupportedrdquo does not mean ldquoperforms wellrdquo
Conditions
ndash Avoid as much as possible
bull if necessary put them last in the shader
ndash Use mix() clamp() etc to create the same result
discard()
ndash Avoid discard()
bull if necessary it should be last
43
Graphics
Audio Solutions
Full track audio
s 45amp026
bull Plays multiple formats with codec support
bull Plays from filesystem or from network
bull Has high latency memory and CPU usage for quick sound effects
Sound effects and clips
s gtI984ampII0
bull Plays multiple formats with codec support
bull Preloads audio files to a pool
ndash Plays them with low latency
44
Sound
Audio Solutions
Application-generated audio
s $945I6T
bull Plays PCM audio only with minimal latency
bull Useful for applications that wish to perform sound processing or mixing
OpenSLES
ndash Combines capabilities of 45amp026 and $945I6T
ndash Available only in the NDK
ndash Requires Android 23 and higher
45
Sound
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
Use native AssetManager
ndash Gingerbread and Beyond
Targeting tricky trying tasks
Troubleshooting Tips and Tricks
47
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
One JNI Context Per Thread
Threading Options
49
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
JNI Context 2
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
OR
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
If all else fails Market filters
ndash Instruction set
ndash ARMv5ARMv7
ndash GL version
ndash Platform release
ndash Use Device Availability
Tips Standing Out from the Crowd
Start Small
ndash Download assets as-needed
ndash Hook me early instead of making me wait
Use Android backuprestore service (save to the cloud)
ndash Keep my progress when I switch devices
Support multiple control schemes
ndash Trackball D-pad virtual stick
ndash Let me decide what works best
Support install-to-SD
ndash Android Market users will knock your ratings if you donrsquot
51
Tips Standing Out from the Crowd
Profiling
ndash In-game profiling to select optimal settings per-device
Social
ndash Hook into social networks
ndash Use OpenID
Build a live wallpaper
ndash Own the userrsquos home screen with stats avatars
Analytics
ndash Market and in-game
In-app payments
ndash Consider alternative monetization techniques
52
Troubleshooting Development Tools
NVIDIA Debug Manager for Eclipse
ndash Simplifies setup for native debugger under Eclipse
bull developernvidiacomtegranvidia-debug-manager-android-ndk
WinGDB
ndash Use Visual Studio to debug Android NDK applications
bull wwwwingdbcom
vs-android
ndash Native MSBuild files for Android toolchain
bull vs-androidgooglecodecom
53
Troubleshooting Performance Tools
NVIDIA PerfHUD ES
ndash developernvidiacomtegraperfhud-es
Adreno Profiler
ndash developerqualcommcomshowcaseadreno-profiler
POWERVR Insider Utilities
ndash Including PVRTrace and PVRTune
ndash wwwimgteccompowervrinsiderpowervr-utilitiesasp
54
developerandroidcomsdkndkGoogleGameDevAndroid
Feedback httpgooglNudVs
QampA
55
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
PXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]LPXJ8Na+EIBER+IBEa+E58R+a+E58R+B7+Z
++E0WW+0W++-]LPXJ8N73dGRBER0WW-LPXJ8Na+IBE7U
++E1R`I4J+54++-]LPXJ8N73dGRR`I4J-+++++++++++++++++++++++++++++LPXJ8Na+0Wa+[RTm2N8RW[a+[-n7=[7U
++-]LPXJ8N73d00=I54R`I4-LPXJ8Na+IBEa+54a+PXJltA7U
Development Flow Calling Dalvik Code Within CC++
20
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Build and Deploy
gt=0Alt-amp49BCDBEFG6HI
ndash Builds C libraries and emits so files
gt)-3
ndash (or ant release)
ndash Builds Java classes apk package
gtamp=44
ndash Deploys to emulator or device
21
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdbgdb-rsp over named pipe
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdb
EclipseVS
gdb-rsp over named pipe
gdb-MI
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Important Tip
B)-36amp3)$$)J23
Bringing Your Game to Android
24
Devices Accessing Android Market
25
Android 16
Android 15
Android 23
Android 233
Android 30
Two Week Period Published May 2011
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
NativeActivity is just starting
ndash 43 of checking-in devices can utilize it
ndash For non-tablet-specific titles we can take advantage of NativeActivity without becoming incompatible
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Platform-specific Resources
Using NativeActivity Compatibly
27
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dV0WcQBII0d++++cBII0+81[8IRG58C6B64[dR69cQBII0dcQ6WI96Wd
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dR69cQBII0d++++cBII0+81[8IRG58C6B64[dV0WcQBII0dcQ6WI96Wd
Using NativeActivity Compatibly
28
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
cR5N5R2+846I54)81[Kgt$XR5N$R5N5R2[+++846I54)8B04[^BII0QRWRG58C6B64[d++c1R34R+846I54)81[846I54KLLK05B81[+++++846I54)N09[W8R5N[+Qd++++++++++++++++++++++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6d++++++++++++cQR5N5R2dcR5N5R2+846I54)81[K1I$R5N5R2[+++846I54)8B04[^BII0Q8IRG58C6B64[d++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6dcQR5N5R2d
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+W8R5N$F$Ggt+)+3$XltJXm$gtltFJgt+ )+C09R50WK+k+ LL3846I5438R5NK$JMgt+)+30GgtND+3040+300IC+30G+30846I54$gt$JJMlt$ltJgt+ )+846I548R5NLLC09$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7-00+51LI6R31I490a846I54Q8R5NLLC097
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
LTC+I1KY1L0KW88C0WU
L9B05+0WW+gt$XR5N$R5N5R2+YR84W+846I54KLLKXR5N$R5N5R2+Z
++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
LTC+I1KY1L0KW88C0WU
L9B05+0WW+1I$R5N5R2+YR84W+846I54KLLK$R5N5R2+Z++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++++++gt2WR1K0I45B662-[WE85[7U++++KKK
Key Game Components
33
Lifecycle
Graphics Sound
Input
Assets
Activity LifecycleLifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Process LifecycleLifecycle
Android keeps application processes around for as long as possible
ndash Even when the activity is closed with V585W`-7 or the back key is pressed
The foreground activity process is considered the most important
ndash It can still be killed as a last resort
Visible activities are also given high priority
ndash Backgrounded activities are considered less important
ndash Processes with no active activities are killed first
Implications of the Process LifecycleLifecycle
Be careful with static initializers
ndash Your library cannot be unloaded while your process is active
bull Donrsquot assume that your static initializers will be run when your activity is created
Be careful with threads
ndash Threads are tied to the process not the activity
bull Your threads will continue to run at reduced priority even if your activity is backgrounded or destroyed
ndash Gameplay should stop during onPause
bull It might make sense to keep certain threads running - your activity may still be visible
ndash Make sure all native code is cleaned up during onDestroy
bull Users expect that your application will no longer be active when its activity is destroyed
The Basics
Key handling
ndash Your device most likely has capacitive buttons
bull Look for complete state transitions of I8m2I_8I8m2AL
bull Avoid overriding 45WLR`m2N8R
ndash Use I8m290R5L0I8m2I8Camp6WW
bull Keep your game behaving like an Android application
TouchMultitouch handling
ndash With I8I9`N8R
bull take advantage of built-in gesture processing
ndash use gt0GWR96RRI6 and GWR96RRI6
ndash Most devices now support multitouch
bull determine if your device can track distinct points
ndash `Wgt2WR1FR96-F$AltA(gtltXAJA(JgtJX)
37
Input
Other Input
Trackball handling
ndash With I86TB00N8R
bull Unhandled events turn into dpad events
Motion handling
ndash With I8gt8WI6`8C4
bull Must be registered with the gt8WI68C6
bull Disable unneeded sensors especially when paused
ndash Active sensors will quickly drain the battery
38
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
OpenGL
GLSurfaceView
ndash Creates the compatible context
bull Contexts are shared between native code and Dalvik
ndash Creates a rendering thread
ndash Releases the context during onPause
ndash Not the most efficient way to multitask withOpenGL but it avoids some driver issues
When context is lost
ndash Reload resources
bull Textures
bull Buffer objects
bull Shaders
ndash Names donrsquot persist
40
Graphics
Texture Formats
Android encourages innovation in hardware
ndash Chipset vendors use several kinds of proprietary texture compression formats
ndash OpenGL ES supports multiple compressed formats none mandatory
Solutions
ndash Uncompressed Textures
ndash Use ETC1 ndash broad support in 20
bull Optimized around photographic data
bull No Alpha
ndash Use Multi-APK (coming soon)
ndash Put textures on an asset server
bull Detect support at runtime
bull Download to each device
41
Graphics
Drawing for Performance
Draw order is important
ndash Has no impact on some platforms means everything on others
ndash Draw front to back to make best use of early rejects
Use VBOs
ndash Avoid unnecessary state changes
Textures
ndash Use power of 2 sized textures
bull It can be very slow
bull On some chipsets not all address modes work
42
Graphics
Writing Compatible Shaders
Query query
ndash Make sure to query for number of attributes varying and uniforms supported
bull Varies between devices
bull Not respecting will make your application crash
bull ldquoSupportedrdquo does not mean ldquoperforms wellrdquo
Conditions
ndash Avoid as much as possible
bull if necessary put them last in the shader
ndash Use mix() clamp() etc to create the same result
discard()
ndash Avoid discard()
bull if necessary it should be last
43
Graphics
Audio Solutions
Full track audio
s 45amp026
bull Plays multiple formats with codec support
bull Plays from filesystem or from network
bull Has high latency memory and CPU usage for quick sound effects
Sound effects and clips
s gtI984ampII0
bull Plays multiple formats with codec support
bull Preloads audio files to a pool
ndash Plays them with low latency
44
Sound
Audio Solutions
Application-generated audio
s $945I6T
bull Plays PCM audio only with minimal latency
bull Useful for applications that wish to perform sound processing or mixing
OpenSLES
ndash Combines capabilities of 45amp026 and $945I6T
ndash Available only in the NDK
ndash Requires Android 23 and higher
45
Sound
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
Use native AssetManager
ndash Gingerbread and Beyond
Targeting tricky trying tasks
Troubleshooting Tips and Tricks
47
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
One JNI Context Per Thread
Threading Options
49
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
JNI Context 2
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
OR
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
If all else fails Market filters
ndash Instruction set
ndash ARMv5ARMv7
ndash GL version
ndash Platform release
ndash Use Device Availability
Tips Standing Out from the Crowd
Start Small
ndash Download assets as-needed
ndash Hook me early instead of making me wait
Use Android backuprestore service (save to the cloud)
ndash Keep my progress when I switch devices
Support multiple control schemes
ndash Trackball D-pad virtual stick
ndash Let me decide what works best
Support install-to-SD
ndash Android Market users will knock your ratings if you donrsquot
51
Tips Standing Out from the Crowd
Profiling
ndash In-game profiling to select optimal settings per-device
Social
ndash Hook into social networks
ndash Use OpenID
Build a live wallpaper
ndash Own the userrsquos home screen with stats avatars
Analytics
ndash Market and in-game
In-app payments
ndash Consider alternative monetization techniques
52
Troubleshooting Development Tools
NVIDIA Debug Manager for Eclipse
ndash Simplifies setup for native debugger under Eclipse
bull developernvidiacomtegranvidia-debug-manager-android-ndk
WinGDB
ndash Use Visual Studio to debug Android NDK applications
bull wwwwingdbcom
vs-android
ndash Native MSBuild files for Android toolchain
bull vs-androidgooglecodecom
53
Troubleshooting Performance Tools
NVIDIA PerfHUD ES
ndash developernvidiacomtegraperfhud-es
Adreno Profiler
ndash developerqualcommcomshowcaseadreno-profiler
POWERVR Insider Utilities
ndash Including PVRTrace and PVRTune
ndash wwwimgteccompowervrinsiderpowervr-utilitiesasp
54
developerandroidcomsdkndkGoogleGameDevAndroid
Feedback httpgooglNudVs
QampA
55
Get native signatures from class file with javap -s +lt=lt+$amp)(12$amp2345amp2675897amp
WRR5+PXJXR5NR`I4+CR`I4Wfg++Z++Z+[585R[a+[-JJ7=[a+-NI54]7+8R5NG1J85R+a+++Z+[WRL[a+[-7=[a+-NI54]7+8R5NgtRL+U
++`6]+0WWX1++[I1Q846I54QC0DE85QGDPXJ5B[U++E0WW+0hh++8N3dF5840WW-0WWX17U++5V+-0hh++XA7+Z++++846I540ICL658R-$XltJGltltlta+[$_WI1G1[a++++++[XR5N+6C5WR6R5I8+98B0+RI+V584+0WW+ijWik8[a+0WWX17U++6R968+PXJF$gtU++++5V+-8N3dltC5WR6XR5NW-0hha+CR`I4Wa+891R`I4W7+c+l7+Z+ 846I540ICL658R-$XltJGltltlta+[$_WI1G1[a+ ++[ltC5WR6XR5NW+V504+VI6+ijWik8[a+0WWX17U++6R968+PXJF$gtU++
Development Flow JNI Glue with Manual Registration
19
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
PXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]LPXJ8Na+EIBER+IBEa+E58R+a+E58R+B7+Z
++E0WW+0W++-]LPXJ8N73dGRBER0WW-LPXJ8Na+IBE7U
++E1R`I4J+54++-]LPXJ8N73dGRR`I4J-+++++++++++++++++++++++++++++LPXJ8Na+0Wa+[RTm2N8RW[a+[-n7=[7U
++-]LPXJ8N73d00=I54R`I4-LPXJ8Na+IBEa+54a+PXJltA7U
Development Flow Calling Dalvik Code Within CC++
20
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Build and Deploy
gt=0Alt-amp49BCDBEFG6HI
ndash Builds C libraries and emits so files
gt)-3
ndash (or ant release)
ndash Builds Java classes apk package
gtamp=44
ndash Deploys to emulator or device
21
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdbgdb-rsp over named pipe
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdb
EclipseVS
gdb-rsp over named pipe
gdb-MI
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Important Tip
B)-36amp3)$$)J23
Bringing Your Game to Android
24
Devices Accessing Android Market
25
Android 16
Android 15
Android 23
Android 233
Android 30
Two Week Period Published May 2011
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
NativeActivity is just starting
ndash 43 of checking-in devices can utilize it
ndash For non-tablet-specific titles we can take advantage of NativeActivity without becoming incompatible
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Platform-specific Resources
Using NativeActivity Compatibly
27
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dV0WcQBII0d++++cBII0+81[8IRG58C6B64[dR69cQBII0dcQ6WI96Wd
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dR69cQBII0d++++cBII0+81[8IRG58C6B64[dV0WcQBII0dcQ6WI96Wd
Using NativeActivity Compatibly
28
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
cR5N5R2+846I54)81[Kgt$XR5N$R5N5R2[+++846I54)8B04[^BII0QRWRG58C6B64[d++c1R34R+846I54)81[846I54KLLK05B81[+++++846I54)N09[W8R5N[+Qd++++++++++++++++++++++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6d++++++++++++cQR5N5R2dcR5N5R2+846I54)81[K1I$R5N5R2[+++846I54)8B04[^BII0Q8IRG58C6B64[d++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6dcQR5N5R2d
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+W8R5N$F$Ggt+)+3$XltJXm$gtltFJgt+ )+C09R50WK+k+ LL3846I5438R5NK$JMgt+)+30GgtND+3040+300IC+30G+30846I54$gt$JJMlt$ltJgt+ )+846I548R5NLLC09$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7-00+51LI6R31I490a846I54Q8R5NLLC097
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
LTC+I1KY1L0KW88C0WU
L9B05+0WW+gt$XR5N$R5N5R2+YR84W+846I54KLLKXR5N$R5N5R2+Z
++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
LTC+I1KY1L0KW88C0WU
L9B05+0WW+1I$R5N5R2+YR84W+846I54KLLK$R5N5R2+Z++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++++++gt2WR1K0I45B662-[WE85[7U++++KKK
Key Game Components
33
Lifecycle
Graphics Sound
Input
Assets
Activity LifecycleLifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Process LifecycleLifecycle
Android keeps application processes around for as long as possible
ndash Even when the activity is closed with V585W`-7 or the back key is pressed
The foreground activity process is considered the most important
ndash It can still be killed as a last resort
Visible activities are also given high priority
ndash Backgrounded activities are considered less important
ndash Processes with no active activities are killed first
Implications of the Process LifecycleLifecycle
Be careful with static initializers
ndash Your library cannot be unloaded while your process is active
bull Donrsquot assume that your static initializers will be run when your activity is created
Be careful with threads
ndash Threads are tied to the process not the activity
bull Your threads will continue to run at reduced priority even if your activity is backgrounded or destroyed
ndash Gameplay should stop during onPause
bull It might make sense to keep certain threads running - your activity may still be visible
ndash Make sure all native code is cleaned up during onDestroy
bull Users expect that your application will no longer be active when its activity is destroyed
The Basics
Key handling
ndash Your device most likely has capacitive buttons
bull Look for complete state transitions of I8m2I_8I8m2AL
bull Avoid overriding 45WLR`m2N8R
ndash Use I8m290R5L0I8m2I8Camp6WW
bull Keep your game behaving like an Android application
TouchMultitouch handling
ndash With I8I9`N8R
bull take advantage of built-in gesture processing
ndash use gt0GWR96RRI6 and GWR96RRI6
ndash Most devices now support multitouch
bull determine if your device can track distinct points
ndash `Wgt2WR1FR96-F$AltA(gtltXAJA(JgtJX)
37
Input
Other Input
Trackball handling
ndash With I86TB00N8R
bull Unhandled events turn into dpad events
Motion handling
ndash With I8gt8WI6`8C4
bull Must be registered with the gt8WI68C6
bull Disable unneeded sensors especially when paused
ndash Active sensors will quickly drain the battery
38
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
OpenGL
GLSurfaceView
ndash Creates the compatible context
bull Contexts are shared between native code and Dalvik
ndash Creates a rendering thread
ndash Releases the context during onPause
ndash Not the most efficient way to multitask withOpenGL but it avoids some driver issues
When context is lost
ndash Reload resources
bull Textures
bull Buffer objects
bull Shaders
ndash Names donrsquot persist
40
Graphics
Texture Formats
Android encourages innovation in hardware
ndash Chipset vendors use several kinds of proprietary texture compression formats
ndash OpenGL ES supports multiple compressed formats none mandatory
Solutions
ndash Uncompressed Textures
ndash Use ETC1 ndash broad support in 20
bull Optimized around photographic data
bull No Alpha
ndash Use Multi-APK (coming soon)
ndash Put textures on an asset server
bull Detect support at runtime
bull Download to each device
41
Graphics
Drawing for Performance
Draw order is important
ndash Has no impact on some platforms means everything on others
ndash Draw front to back to make best use of early rejects
Use VBOs
ndash Avoid unnecessary state changes
Textures
ndash Use power of 2 sized textures
bull It can be very slow
bull On some chipsets not all address modes work
42
Graphics
Writing Compatible Shaders
Query query
ndash Make sure to query for number of attributes varying and uniforms supported
bull Varies between devices
bull Not respecting will make your application crash
bull ldquoSupportedrdquo does not mean ldquoperforms wellrdquo
Conditions
ndash Avoid as much as possible
bull if necessary put them last in the shader
ndash Use mix() clamp() etc to create the same result
discard()
ndash Avoid discard()
bull if necessary it should be last
43
Graphics
Audio Solutions
Full track audio
s 45amp026
bull Plays multiple formats with codec support
bull Plays from filesystem or from network
bull Has high latency memory and CPU usage for quick sound effects
Sound effects and clips
s gtI984ampII0
bull Plays multiple formats with codec support
bull Preloads audio files to a pool
ndash Plays them with low latency
44
Sound
Audio Solutions
Application-generated audio
s $945I6T
bull Plays PCM audio only with minimal latency
bull Useful for applications that wish to perform sound processing or mixing
OpenSLES
ndash Combines capabilities of 45amp026 and $945I6T
ndash Available only in the NDK
ndash Requires Android 23 and higher
45
Sound
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
Use native AssetManager
ndash Gingerbread and Beyond
Targeting tricky trying tasks
Troubleshooting Tips and Tricks
47
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
One JNI Context Per Thread
Threading Options
49
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
JNI Context 2
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
OR
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
If all else fails Market filters
ndash Instruction set
ndash ARMv5ARMv7
ndash GL version
ndash Platform release
ndash Use Device Availability
Tips Standing Out from the Crowd
Start Small
ndash Download assets as-needed
ndash Hook me early instead of making me wait
Use Android backuprestore service (save to the cloud)
ndash Keep my progress when I switch devices
Support multiple control schemes
ndash Trackball D-pad virtual stick
ndash Let me decide what works best
Support install-to-SD
ndash Android Market users will knock your ratings if you donrsquot
51
Tips Standing Out from the Crowd
Profiling
ndash In-game profiling to select optimal settings per-device
Social
ndash Hook into social networks
ndash Use OpenID
Build a live wallpaper
ndash Own the userrsquos home screen with stats avatars
Analytics
ndash Market and in-game
In-app payments
ndash Consider alternative monetization techniques
52
Troubleshooting Development Tools
NVIDIA Debug Manager for Eclipse
ndash Simplifies setup for native debugger under Eclipse
bull developernvidiacomtegranvidia-debug-manager-android-ndk
WinGDB
ndash Use Visual Studio to debug Android NDK applications
bull wwwwingdbcom
vs-android
ndash Native MSBuild files for Android toolchain
bull vs-androidgooglecodecom
53
Troubleshooting Performance Tools
NVIDIA PerfHUD ES
ndash developernvidiacomtegraperfhud-es
Adreno Profiler
ndash developerqualcommcomshowcaseadreno-profiler
POWERVR Insider Utilities
ndash Including PVRTrace and PVRTune
ndash wwwimgteccompowervrinsiderpowervr-utilitiesasp
54
developerandroidcomsdkndkGoogleGameDevAndroid
Feedback httpgooglNudVs
QampA
55
PXJeamplt+NI54+PXJ$+PNI1846I54C0DE85GDPXJ5B585R++-PXJ8N+]LPXJ8Na+EIBER+IBEa+E58R+a+E58R+B7+Z
++E0WW+0W++-]LPXJ8N73dGRBER0WW-LPXJ8Na+IBE7U
++E1R`I4J+54++-]LPXJ8N73dGRR`I4J-+++++++++++++++++++++++++++++LPXJ8Na+0Wa+[RTm2N8RW[a+[-n7=[7U
++-]LPXJ8N73d00=I54R`I4-LPXJ8Na+IBEa+54a+PXJltA7U
Development Flow Calling Dalvik Code Within CC++
20
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Development Flow Build and Deploy
gt=0Alt-amp49BCDBEFG6HI
ndash Builds C libraries and emits so files
gt)-3
ndash (or ant release)
ndash Builds Java classes apk package
gtamp=44
ndash Deploys to emulator or device
21
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdbgdb-rsp over named pipe
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdb
EclipseVS
gdb-rsp over named pipe
gdb-MI
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Important Tip
B)-36amp3)$$)J23
Bringing Your Game to Android
24
Devices Accessing Android Market
25
Android 16
Android 15
Android 23
Android 233
Android 30
Two Week Period Published May 2011
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
NativeActivity is just starting
ndash 43 of checking-in devices can utilize it
ndash For non-tablet-specific titles we can take advantage of NativeActivity without becoming incompatible
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Platform-specific Resources
Using NativeActivity Compatibly
27
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dV0WcQBII0d++++cBII0+81[8IRG58C6B64[dR69cQBII0dcQ6WI96Wd
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dR69cQBII0d++++cBII0+81[8IRG58C6B64[dV0WcQBII0dcQ6WI96Wd
Using NativeActivity Compatibly
28
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
cR5N5R2+846I54)81[Kgt$XR5N$R5N5R2[+++846I54)8B04[^BII0QRWRG58C6B64[d++c1R34R+846I54)81[846I54KLLK05B81[+++++846I54)N09[W8R5N[+Qd++++++++++++++++++++++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6d++++++++++++cQR5N5R2dcR5N5R2+846I54)81[K1I$R5N5R2[+++846I54)8B04[^BII0Q8IRG58C6B64[d++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6dcQR5N5R2d
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+W8R5N$F$Ggt+)+3$XltJXm$gtltFJgt+ )+C09R50WK+k+ LL3846I5438R5NK$JMgt+)+30GgtND+3040+300IC+30G+30846I54$gt$JJMlt$ltJgt+ )+846I548R5NLLC09$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7-00+51LI6R31I490a846I54Q8R5NLLC097
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
LTC+I1KY1L0KW88C0WU
L9B05+0WW+gt$XR5N$R5N5R2+YR84W+846I54KLLKXR5N$R5N5R2+Z
++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
LTC+I1KY1L0KW88C0WU
L9B05+0WW+1I$R5N5R2+YR84W+846I54KLLK$R5N5R2+Z++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++++++gt2WR1K0I45B662-[WE85[7U++++KKK
Key Game Components
33
Lifecycle
Graphics Sound
Input
Assets
Activity LifecycleLifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Process LifecycleLifecycle
Android keeps application processes around for as long as possible
ndash Even when the activity is closed with V585W`-7 or the back key is pressed
The foreground activity process is considered the most important
ndash It can still be killed as a last resort
Visible activities are also given high priority
ndash Backgrounded activities are considered less important
ndash Processes with no active activities are killed first
Implications of the Process LifecycleLifecycle
Be careful with static initializers
ndash Your library cannot be unloaded while your process is active
bull Donrsquot assume that your static initializers will be run when your activity is created
Be careful with threads
ndash Threads are tied to the process not the activity
bull Your threads will continue to run at reduced priority even if your activity is backgrounded or destroyed
ndash Gameplay should stop during onPause
bull It might make sense to keep certain threads running - your activity may still be visible
ndash Make sure all native code is cleaned up during onDestroy
bull Users expect that your application will no longer be active when its activity is destroyed
The Basics
Key handling
ndash Your device most likely has capacitive buttons
bull Look for complete state transitions of I8m2I_8I8m2AL
bull Avoid overriding 45WLR`m2N8R
ndash Use I8m290R5L0I8m2I8Camp6WW
bull Keep your game behaving like an Android application
TouchMultitouch handling
ndash With I8I9`N8R
bull take advantage of built-in gesture processing
ndash use gt0GWR96RRI6 and GWR96RRI6
ndash Most devices now support multitouch
bull determine if your device can track distinct points
ndash `Wgt2WR1FR96-F$AltA(gtltXAJA(JgtJX)
37
Input
Other Input
Trackball handling
ndash With I86TB00N8R
bull Unhandled events turn into dpad events
Motion handling
ndash With I8gt8WI6`8C4
bull Must be registered with the gt8WI68C6
bull Disable unneeded sensors especially when paused
ndash Active sensors will quickly drain the battery
38
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
OpenGL
GLSurfaceView
ndash Creates the compatible context
bull Contexts are shared between native code and Dalvik
ndash Creates a rendering thread
ndash Releases the context during onPause
ndash Not the most efficient way to multitask withOpenGL but it avoids some driver issues
When context is lost
ndash Reload resources
bull Textures
bull Buffer objects
bull Shaders
ndash Names donrsquot persist
40
Graphics
Texture Formats
Android encourages innovation in hardware
ndash Chipset vendors use several kinds of proprietary texture compression formats
ndash OpenGL ES supports multiple compressed formats none mandatory
Solutions
ndash Uncompressed Textures
ndash Use ETC1 ndash broad support in 20
bull Optimized around photographic data
bull No Alpha
ndash Use Multi-APK (coming soon)
ndash Put textures on an asset server
bull Detect support at runtime
bull Download to each device
41
Graphics
Drawing for Performance
Draw order is important
ndash Has no impact on some platforms means everything on others
ndash Draw front to back to make best use of early rejects
Use VBOs
ndash Avoid unnecessary state changes
Textures
ndash Use power of 2 sized textures
bull It can be very slow
bull On some chipsets not all address modes work
42
Graphics
Writing Compatible Shaders
Query query
ndash Make sure to query for number of attributes varying and uniforms supported
bull Varies between devices
bull Not respecting will make your application crash
bull ldquoSupportedrdquo does not mean ldquoperforms wellrdquo
Conditions
ndash Avoid as much as possible
bull if necessary put them last in the shader
ndash Use mix() clamp() etc to create the same result
discard()
ndash Avoid discard()
bull if necessary it should be last
43
Graphics
Audio Solutions
Full track audio
s 45amp026
bull Plays multiple formats with codec support
bull Plays from filesystem or from network
bull Has high latency memory and CPU usage for quick sound effects
Sound effects and clips
s gtI984ampII0
bull Plays multiple formats with codec support
bull Preloads audio files to a pool
ndash Plays them with low latency
44
Sound
Audio Solutions
Application-generated audio
s $945I6T
bull Plays PCM audio only with minimal latency
bull Useful for applications that wish to perform sound processing or mixing
OpenSLES
ndash Combines capabilities of 45amp026 and $945I6T
ndash Available only in the NDK
ndash Requires Android 23 and higher
45
Sound
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
Use native AssetManager
ndash Gingerbread and Beyond
Targeting tricky trying tasks
Troubleshooting Tips and Tricks
47
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
One JNI Context Per Thread
Threading Options
49
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
JNI Context 2
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
OR
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
If all else fails Market filters
ndash Instruction set
ndash ARMv5ARMv7
ndash GL version
ndash Platform release
ndash Use Device Availability
Tips Standing Out from the Crowd
Start Small
ndash Download assets as-needed
ndash Hook me early instead of making me wait
Use Android backuprestore service (save to the cloud)
ndash Keep my progress when I switch devices
Support multiple control schemes
ndash Trackball D-pad virtual stick
ndash Let me decide what works best
Support install-to-SD
ndash Android Market users will knock your ratings if you donrsquot
51
Tips Standing Out from the Crowd
Profiling
ndash In-game profiling to select optimal settings per-device
Social
ndash Hook into social networks
ndash Use OpenID
Build a live wallpaper
ndash Own the userrsquos home screen with stats avatars
Analytics
ndash Market and in-game
In-app payments
ndash Consider alternative monetization techniques
52
Troubleshooting Development Tools
NVIDIA Debug Manager for Eclipse
ndash Simplifies setup for native debugger under Eclipse
bull developernvidiacomtegranvidia-debug-manager-android-ndk
WinGDB
ndash Use Visual Studio to debug Android NDK applications
bull wwwwingdbcom
vs-android
ndash Native MSBuild files for Android toolchain
bull vs-androidgooglecodecom
53
Troubleshooting Performance Tools
NVIDIA PerfHUD ES
ndash developernvidiacomtegraperfhud-es
Adreno Profiler
ndash developerqualcommcomshowcaseadreno-profiler
POWERVR Insider Utilities
ndash Including PVRTrace and PVRTune
ndash wwwimgteccompowervrinsiderpowervr-utilitiesasp
54
developerandroidcomsdkndkGoogleGameDevAndroid
Feedback httpgooglNudVs
QampA
55
Development Flow Build and Deploy
gt=0Alt-amp49BCDBEFG6HI
ndash Builds C libraries and emits so files
gt)-3
ndash (or ant release)
ndash Builds Java classes apk package
gtamp=44
ndash Deploys to emulator or device
21
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdbgdb-rsp over named pipe
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdb
EclipseVS
gdb-rsp over named pipe
gdb-MI
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Important Tip
B)-36amp3)$$)J23
Bringing Your Game to Android
24
Devices Accessing Android Market
25
Android 16
Android 15
Android 23
Android 233
Android 30
Two Week Period Published May 2011
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
NativeActivity is just starting
ndash 43 of checking-in devices can utilize it
ndash For non-tablet-specific titles we can take advantage of NativeActivity without becoming incompatible
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Platform-specific Resources
Using NativeActivity Compatibly
27
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dV0WcQBII0d++++cBII0+81[8IRG58C6B64[dR69cQBII0dcQ6WI96Wd
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dR69cQBII0d++++cBII0+81[8IRG58C6B64[dV0WcQBII0dcQ6WI96Wd
Using NativeActivity Compatibly
28
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
cR5N5R2+846I54)81[Kgt$XR5N$R5N5R2[+++846I54)8B04[^BII0QRWRG58C6B64[d++c1R34R+846I54)81[846I54KLLK05B81[+++++846I54)N09[W8R5N[+Qd++++++++++++++++++++++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6d++++++++++++cQR5N5R2dcR5N5R2+846I54)81[K1I$R5N5R2[+++846I54)8B04[^BII0Q8IRG58C6B64[d++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6dcQR5N5R2d
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+W8R5N$F$Ggt+)+3$XltJXm$gtltFJgt+ )+C09R50WK+k+ LL3846I5438R5NK$JMgt+)+30GgtND+3040+300IC+30G+30846I54$gt$JJMlt$ltJgt+ )+846I548R5NLLC09$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7-00+51LI6R31I490a846I54Q8R5NLLC097
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
LTC+I1KY1L0KW88C0WU
L9B05+0WW+gt$XR5N$R5N5R2+YR84W+846I54KLLKXR5N$R5N5R2+Z
++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
LTC+I1KY1L0KW88C0WU
L9B05+0WW+1I$R5N5R2+YR84W+846I54KLLK$R5N5R2+Z++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++++++gt2WR1K0I45B662-[WE85[7U++++KKK
Key Game Components
33
Lifecycle
Graphics Sound
Input
Assets
Activity LifecycleLifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Process LifecycleLifecycle
Android keeps application processes around for as long as possible
ndash Even when the activity is closed with V585W`-7 or the back key is pressed
The foreground activity process is considered the most important
ndash It can still be killed as a last resort
Visible activities are also given high priority
ndash Backgrounded activities are considered less important
ndash Processes with no active activities are killed first
Implications of the Process LifecycleLifecycle
Be careful with static initializers
ndash Your library cannot be unloaded while your process is active
bull Donrsquot assume that your static initializers will be run when your activity is created
Be careful with threads
ndash Threads are tied to the process not the activity
bull Your threads will continue to run at reduced priority even if your activity is backgrounded or destroyed
ndash Gameplay should stop during onPause
bull It might make sense to keep certain threads running - your activity may still be visible
ndash Make sure all native code is cleaned up during onDestroy
bull Users expect that your application will no longer be active when its activity is destroyed
The Basics
Key handling
ndash Your device most likely has capacitive buttons
bull Look for complete state transitions of I8m2I_8I8m2AL
bull Avoid overriding 45WLR`m2N8R
ndash Use I8m290R5L0I8m2I8Camp6WW
bull Keep your game behaving like an Android application
TouchMultitouch handling
ndash With I8I9`N8R
bull take advantage of built-in gesture processing
ndash use gt0GWR96RRI6 and GWR96RRI6
ndash Most devices now support multitouch
bull determine if your device can track distinct points
ndash `Wgt2WR1FR96-F$AltA(gtltXAJA(JgtJX)
37
Input
Other Input
Trackball handling
ndash With I86TB00N8R
bull Unhandled events turn into dpad events
Motion handling
ndash With I8gt8WI6`8C4
bull Must be registered with the gt8WI68C6
bull Disable unneeded sensors especially when paused
ndash Active sensors will quickly drain the battery
38
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
OpenGL
GLSurfaceView
ndash Creates the compatible context
bull Contexts are shared between native code and Dalvik
ndash Creates a rendering thread
ndash Releases the context during onPause
ndash Not the most efficient way to multitask withOpenGL but it avoids some driver issues
When context is lost
ndash Reload resources
bull Textures
bull Buffer objects
bull Shaders
ndash Names donrsquot persist
40
Graphics
Texture Formats
Android encourages innovation in hardware
ndash Chipset vendors use several kinds of proprietary texture compression formats
ndash OpenGL ES supports multiple compressed formats none mandatory
Solutions
ndash Uncompressed Textures
ndash Use ETC1 ndash broad support in 20
bull Optimized around photographic data
bull No Alpha
ndash Use Multi-APK (coming soon)
ndash Put textures on an asset server
bull Detect support at runtime
bull Download to each device
41
Graphics
Drawing for Performance
Draw order is important
ndash Has no impact on some platforms means everything on others
ndash Draw front to back to make best use of early rejects
Use VBOs
ndash Avoid unnecessary state changes
Textures
ndash Use power of 2 sized textures
bull It can be very slow
bull On some chipsets not all address modes work
42
Graphics
Writing Compatible Shaders
Query query
ndash Make sure to query for number of attributes varying and uniforms supported
bull Varies between devices
bull Not respecting will make your application crash
bull ldquoSupportedrdquo does not mean ldquoperforms wellrdquo
Conditions
ndash Avoid as much as possible
bull if necessary put them last in the shader
ndash Use mix() clamp() etc to create the same result
discard()
ndash Avoid discard()
bull if necessary it should be last
43
Graphics
Audio Solutions
Full track audio
s 45amp026
bull Plays multiple formats with codec support
bull Plays from filesystem or from network
bull Has high latency memory and CPU usage for quick sound effects
Sound effects and clips
s gtI984ampII0
bull Plays multiple formats with codec support
bull Preloads audio files to a pool
ndash Plays them with low latency
44
Sound
Audio Solutions
Application-generated audio
s $945I6T
bull Plays PCM audio only with minimal latency
bull Useful for applications that wish to perform sound processing or mixing
OpenSLES
ndash Combines capabilities of 45amp026 and $945I6T
ndash Available only in the NDK
ndash Requires Android 23 and higher
45
Sound
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
Use native AssetManager
ndash Gingerbread and Beyond
Targeting tricky trying tasks
Troubleshooting Tips and Tricks
47
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
One JNI Context Per Thread
Threading Options
49
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
JNI Context 2
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
OR
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
If all else fails Market filters
ndash Instruction set
ndash ARMv5ARMv7
ndash GL version
ndash Platform release
ndash Use Device Availability
Tips Standing Out from the Crowd
Start Small
ndash Download assets as-needed
ndash Hook me early instead of making me wait
Use Android backuprestore service (save to the cloud)
ndash Keep my progress when I switch devices
Support multiple control schemes
ndash Trackball D-pad virtual stick
ndash Let me decide what works best
Support install-to-SD
ndash Android Market users will knock your ratings if you donrsquot
51
Tips Standing Out from the Crowd
Profiling
ndash In-game profiling to select optimal settings per-device
Social
ndash Hook into social networks
ndash Use OpenID
Build a live wallpaper
ndash Own the userrsquos home screen with stats avatars
Analytics
ndash Market and in-game
In-app payments
ndash Consider alternative monetization techniques
52
Troubleshooting Development Tools
NVIDIA Debug Manager for Eclipse
ndash Simplifies setup for native debugger under Eclipse
bull developernvidiacomtegranvidia-debug-manager-android-ndk
WinGDB
ndash Use Visual Studio to debug Android NDK applications
bull wwwwingdbcom
vs-android
ndash Native MSBuild files for Android toolchain
bull vs-androidgooglecodecom
53
Troubleshooting Performance Tools
NVIDIA PerfHUD ES
ndash developernvidiacomtegraperfhud-es
Adreno Profiler
ndash developerqualcommcomshowcaseadreno-profiler
POWERVR Insider Utilities
ndash Including PVRTrace and PVRTune
ndash wwwimgteccompowervrinsiderpowervr-utilitiesasp
54
developerandroidcomsdkndkGoogleGameDevAndroid
Feedback httpgooglNudVs
QampA
55
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdbgdb-rsp over named pipe
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdb
EclipseVS
gdb-rsp over named pipe
gdb-MI
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Important Tip
B)-36amp3)$$)J23
Bringing Your Game to Android
24
Devices Accessing Android Market
25
Android 16
Android 15
Android 23
Android 233
Android 30
Two Week Period Published May 2011
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
NativeActivity is just starting
ndash 43 of checking-in devices can utilize it
ndash For non-tablet-specific titles we can take advantage of NativeActivity without becoming incompatible
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Platform-specific Resources
Using NativeActivity Compatibly
27
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dV0WcQBII0d++++cBII0+81[8IRG58C6B64[dR69cQBII0dcQ6WI96Wd
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dR69cQBII0d++++cBII0+81[8IRG58C6B64[dV0WcQBII0dcQ6WI96Wd
Using NativeActivity Compatibly
28
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
cR5N5R2+846I54)81[Kgt$XR5N$R5N5R2[+++846I54)8B04[^BII0QRWRG58C6B64[d++c1R34R+846I54)81[846I54KLLK05B81[+++++846I54)N09[W8R5N[+Qd++++++++++++++++++++++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6d++++++++++++cQR5N5R2dcR5N5R2+846I54)81[K1I$R5N5R2[+++846I54)8B04[^BII0Q8IRG58C6B64[d++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6dcQR5N5R2d
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+W8R5N$F$Ggt+)+3$XltJXm$gtltFJgt+ )+C09R50WK+k+ LL3846I5438R5NK$JMgt+)+30GgtND+3040+300IC+30G+30846I54$gt$JJMlt$ltJgt+ )+846I548R5NLLC09$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7-00+51LI6R31I490a846I54Q8R5NLLC097
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
LTC+I1KY1L0KW88C0WU
L9B05+0WW+gt$XR5N$R5N5R2+YR84W+846I54KLLKXR5N$R5N5R2+Z
++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
LTC+I1KY1L0KW88C0WU
L9B05+0WW+1I$R5N5R2+YR84W+846I54KLLK$R5N5R2+Z++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++++++gt2WR1K0I45B662-[WE85[7U++++KKK
Key Game Components
33
Lifecycle
Graphics Sound
Input
Assets
Activity LifecycleLifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Process LifecycleLifecycle
Android keeps application processes around for as long as possible
ndash Even when the activity is closed with V585W`-7 or the back key is pressed
The foreground activity process is considered the most important
ndash It can still be killed as a last resort
Visible activities are also given high priority
ndash Backgrounded activities are considered less important
ndash Processes with no active activities are killed first
Implications of the Process LifecycleLifecycle
Be careful with static initializers
ndash Your library cannot be unloaded while your process is active
bull Donrsquot assume that your static initializers will be run when your activity is created
Be careful with threads
ndash Threads are tied to the process not the activity
bull Your threads will continue to run at reduced priority even if your activity is backgrounded or destroyed
ndash Gameplay should stop during onPause
bull It might make sense to keep certain threads running - your activity may still be visible
ndash Make sure all native code is cleaned up during onDestroy
bull Users expect that your application will no longer be active when its activity is destroyed
The Basics
Key handling
ndash Your device most likely has capacitive buttons
bull Look for complete state transitions of I8m2I_8I8m2AL
bull Avoid overriding 45WLR`m2N8R
ndash Use I8m290R5L0I8m2I8Camp6WW
bull Keep your game behaving like an Android application
TouchMultitouch handling
ndash With I8I9`N8R
bull take advantage of built-in gesture processing
ndash use gt0GWR96RRI6 and GWR96RRI6
ndash Most devices now support multitouch
bull determine if your device can track distinct points
ndash `Wgt2WR1FR96-F$AltA(gtltXAJA(JgtJX)
37
Input
Other Input
Trackball handling
ndash With I86TB00N8R
bull Unhandled events turn into dpad events
Motion handling
ndash With I8gt8WI6`8C4
bull Must be registered with the gt8WI68C6
bull Disable unneeded sensors especially when paused
ndash Active sensors will quickly drain the battery
38
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
OpenGL
GLSurfaceView
ndash Creates the compatible context
bull Contexts are shared between native code and Dalvik
ndash Creates a rendering thread
ndash Releases the context during onPause
ndash Not the most efficient way to multitask withOpenGL but it avoids some driver issues
When context is lost
ndash Reload resources
bull Textures
bull Buffer objects
bull Shaders
ndash Names donrsquot persist
40
Graphics
Texture Formats
Android encourages innovation in hardware
ndash Chipset vendors use several kinds of proprietary texture compression formats
ndash OpenGL ES supports multiple compressed formats none mandatory
Solutions
ndash Uncompressed Textures
ndash Use ETC1 ndash broad support in 20
bull Optimized around photographic data
bull No Alpha
ndash Use Multi-APK (coming soon)
ndash Put textures on an asset server
bull Detect support at runtime
bull Download to each device
41
Graphics
Drawing for Performance
Draw order is important
ndash Has no impact on some platforms means everything on others
ndash Draw front to back to make best use of early rejects
Use VBOs
ndash Avoid unnecessary state changes
Textures
ndash Use power of 2 sized textures
bull It can be very slow
bull On some chipsets not all address modes work
42
Graphics
Writing Compatible Shaders
Query query
ndash Make sure to query for number of attributes varying and uniforms supported
bull Varies between devices
bull Not respecting will make your application crash
bull ldquoSupportedrdquo does not mean ldquoperforms wellrdquo
Conditions
ndash Avoid as much as possible
bull if necessary put them last in the shader
ndash Use mix() clamp() etc to create the same result
discard()
ndash Avoid discard()
bull if necessary it should be last
43
Graphics
Audio Solutions
Full track audio
s 45amp026
bull Plays multiple formats with codec support
bull Plays from filesystem or from network
bull Has high latency memory and CPU usage for quick sound effects
Sound effects and clips
s gtI984ampII0
bull Plays multiple formats with codec support
bull Preloads audio files to a pool
ndash Plays them with low latency
44
Sound
Audio Solutions
Application-generated audio
s $945I6T
bull Plays PCM audio only with minimal latency
bull Useful for applications that wish to perform sound processing or mixing
OpenSLES
ndash Combines capabilities of 45amp026 and $945I6T
ndash Available only in the NDK
ndash Requires Android 23 and higher
45
Sound
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
Use native AssetManager
ndash Gingerbread and Beyond
Targeting tricky trying tasks
Troubleshooting Tips and Tricks
47
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
One JNI Context Per Thread
Threading Options
49
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
JNI Context 2
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
OR
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
If all else fails Market filters
ndash Instruction set
ndash ARMv5ARMv7
ndash GL version
ndash Platform release
ndash Use Device Availability
Tips Standing Out from the Crowd
Start Small
ndash Download assets as-needed
ndash Hook me early instead of making me wait
Use Android backuprestore service (save to the cloud)
ndash Keep my progress when I switch devices
Support multiple control schemes
ndash Trackball D-pad virtual stick
ndash Let me decide what works best
Support install-to-SD
ndash Android Market users will knock your ratings if you donrsquot
51
Tips Standing Out from the Crowd
Profiling
ndash In-game profiling to select optimal settings per-device
Social
ndash Hook into social networks
ndash Use OpenID
Build a live wallpaper
ndash Own the userrsquos home screen with stats avatars
Analytics
ndash Market and in-game
In-app payments
ndash Consider alternative monetization techniques
52
Troubleshooting Development Tools
NVIDIA Debug Manager for Eclipse
ndash Simplifies setup for native debugger under Eclipse
bull developernvidiacomtegranvidia-debug-manager-android-ndk
WinGDB
ndash Use Visual Studio to debug Android NDK applications
bull wwwwingdbcom
vs-android
ndash Native MSBuild files for Android toolchain
bull vs-androidgooglecodecom
53
Troubleshooting Performance Tools
NVIDIA PerfHUD ES
ndash developernvidiacomtegraperfhud-es
Adreno Profiler
ndash developerqualcommcomshowcaseadreno-profiler
POWERVR Insider Utilities
ndash Including PVRTrace and PVRTune
ndash wwwimgteccompowervrinsiderpowervr-utilitiesasp
54
developerandroidcomsdkndkGoogleGameDevAndroid
Feedback httpgooglNudVs
QampA
55
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdbgdb-rsp over named pipe
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdb
EclipseVS
gdb-rsp over named pipe
gdb-MI
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Important Tip
B)-36amp3)$$)J23
Bringing Your Game to Android
24
Devices Accessing Android Market
25
Android 16
Android 15
Android 23
Android 233
Android 30
Two Week Period Published May 2011
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
NativeActivity is just starting
ndash 43 of checking-in devices can utilize it
ndash For non-tablet-specific titles we can take advantage of NativeActivity without becoming incompatible
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Platform-specific Resources
Using NativeActivity Compatibly
27
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dV0WcQBII0d++++cBII0+81[8IRG58C6B64[dR69cQBII0dcQ6WI96Wd
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dR69cQBII0d++++cBII0+81[8IRG58C6B64[dV0WcQBII0dcQ6WI96Wd
Using NativeActivity Compatibly
28
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
cR5N5R2+846I54)81[Kgt$XR5N$R5N5R2[+++846I54)8B04[^BII0QRWRG58C6B64[d++c1R34R+846I54)81[846I54KLLK05B81[+++++846I54)N09[W8R5N[+Qd++++++++++++++++++++++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6d++++++++++++cQR5N5R2dcR5N5R2+846I54)81[K1I$R5N5R2[+++846I54)8B04[^BII0Q8IRG58C6B64[d++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6dcQR5N5R2d
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+W8R5N$F$Ggt+)+3$XltJXm$gtltFJgt+ )+C09R50WK+k+ LL3846I5438R5NK$JMgt+)+30GgtND+3040+300IC+30G+30846I54$gt$JJMlt$ltJgt+ )+846I548R5NLLC09$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7-00+51LI6R31I490a846I54Q8R5NLLC097
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
LTC+I1KY1L0KW88C0WU
L9B05+0WW+gt$XR5N$R5N5R2+YR84W+846I54KLLKXR5N$R5N5R2+Z
++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
LTC+I1KY1L0KW88C0WU
L9B05+0WW+1I$R5N5R2+YR84W+846I54KLLK$R5N5R2+Z++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++++++gt2WR1K0I45B662-[WE85[7U++++KKK
Key Game Components
33
Lifecycle
Graphics Sound
Input
Assets
Activity LifecycleLifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Process LifecycleLifecycle
Android keeps application processes around for as long as possible
ndash Even when the activity is closed with V585W`-7 or the back key is pressed
The foreground activity process is considered the most important
ndash It can still be killed as a last resort
Visible activities are also given high priority
ndash Backgrounded activities are considered less important
ndash Processes with no active activities are killed first
Implications of the Process LifecycleLifecycle
Be careful with static initializers
ndash Your library cannot be unloaded while your process is active
bull Donrsquot assume that your static initializers will be run when your activity is created
Be careful with threads
ndash Threads are tied to the process not the activity
bull Your threads will continue to run at reduced priority even if your activity is backgrounded or destroyed
ndash Gameplay should stop during onPause
bull It might make sense to keep certain threads running - your activity may still be visible
ndash Make sure all native code is cleaned up during onDestroy
bull Users expect that your application will no longer be active when its activity is destroyed
The Basics
Key handling
ndash Your device most likely has capacitive buttons
bull Look for complete state transitions of I8m2I_8I8m2AL
bull Avoid overriding 45WLR`m2N8R
ndash Use I8m290R5L0I8m2I8Camp6WW
bull Keep your game behaving like an Android application
TouchMultitouch handling
ndash With I8I9`N8R
bull take advantage of built-in gesture processing
ndash use gt0GWR96RRI6 and GWR96RRI6
ndash Most devices now support multitouch
bull determine if your device can track distinct points
ndash `Wgt2WR1FR96-F$AltA(gtltXAJA(JgtJX)
37
Input
Other Input
Trackball handling
ndash With I86TB00N8R
bull Unhandled events turn into dpad events
Motion handling
ndash With I8gt8WI6`8C4
bull Must be registered with the gt8WI68C6
bull Disable unneeded sensors especially when paused
ndash Active sensors will quickly drain the battery
38
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
OpenGL
GLSurfaceView
ndash Creates the compatible context
bull Contexts are shared between native code and Dalvik
ndash Creates a rendering thread
ndash Releases the context during onPause
ndash Not the most efficient way to multitask withOpenGL but it avoids some driver issues
When context is lost
ndash Reload resources
bull Textures
bull Buffer objects
bull Shaders
ndash Names donrsquot persist
40
Graphics
Texture Formats
Android encourages innovation in hardware
ndash Chipset vendors use several kinds of proprietary texture compression formats
ndash OpenGL ES supports multiple compressed formats none mandatory
Solutions
ndash Uncompressed Textures
ndash Use ETC1 ndash broad support in 20
bull Optimized around photographic data
bull No Alpha
ndash Use Multi-APK (coming soon)
ndash Put textures on an asset server
bull Detect support at runtime
bull Download to each device
41
Graphics
Drawing for Performance
Draw order is important
ndash Has no impact on some platforms means everything on others
ndash Draw front to back to make best use of early rejects
Use VBOs
ndash Avoid unnecessary state changes
Textures
ndash Use power of 2 sized textures
bull It can be very slow
bull On some chipsets not all address modes work
42
Graphics
Writing Compatible Shaders
Query query
ndash Make sure to query for number of attributes varying and uniforms supported
bull Varies between devices
bull Not respecting will make your application crash
bull ldquoSupportedrdquo does not mean ldquoperforms wellrdquo
Conditions
ndash Avoid as much as possible
bull if necessary put them last in the shader
ndash Use mix() clamp() etc to create the same result
discard()
ndash Avoid discard()
bull if necessary it should be last
43
Graphics
Audio Solutions
Full track audio
s 45amp026
bull Plays multiple formats with codec support
bull Plays from filesystem or from network
bull Has high latency memory and CPU usage for quick sound effects
Sound effects and clips
s gtI984ampII0
bull Plays multiple formats with codec support
bull Preloads audio files to a pool
ndash Plays them with low latency
44
Sound
Audio Solutions
Application-generated audio
s $945I6T
bull Plays PCM audio only with minimal latency
bull Useful for applications that wish to perform sound processing or mixing
OpenSLES
ndash Combines capabilities of 45amp026 and $945I6T
ndash Available only in the NDK
ndash Requires Android 23 and higher
45
Sound
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
Use native AssetManager
ndash Gingerbread and Beyond
Targeting tricky trying tasks
Troubleshooting Tips and Tricks
47
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
One JNI Context Per Thread
Threading Options
49
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
JNI Context 2
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
OR
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
If all else fails Market filters
ndash Instruction set
ndash ARMv5ARMv7
ndash GL version
ndash Platform release
ndash Use Device Availability
Tips Standing Out from the Crowd
Start Small
ndash Download assets as-needed
ndash Hook me early instead of making me wait
Use Android backuprestore service (save to the cloud)
ndash Keep my progress when I switch devices
Support multiple control schemes
ndash Trackball D-pad virtual stick
ndash Let me decide what works best
Support install-to-SD
ndash Android Market users will knock your ratings if you donrsquot
51
Tips Standing Out from the Crowd
Profiling
ndash In-game profiling to select optimal settings per-device
Social
ndash Hook into social networks
ndash Use OpenID
Build a live wallpaper
ndash Own the userrsquos home screen with stats avatars
Analytics
ndash Market and in-game
In-app payments
ndash Consider alternative monetization techniques
52
Troubleshooting Development Tools
NVIDIA Debug Manager for Eclipse
ndash Simplifies setup for native debugger under Eclipse
bull developernvidiacomtegranvidia-debug-manager-android-ndk
WinGDB
ndash Use Visual Studio to debug Android NDK applications
bull wwwwingdbcom
vs-android
ndash Native MSBuild files for Android toolchain
bull vs-androidgooglecodecom
53
Troubleshooting Performance Tools
NVIDIA PerfHUD ES
ndash developernvidiacomtegraperfhud-es
Adreno Profiler
ndash developerqualcommcomshowcaseadreno-profiler
POWERVR Insider Utilities
ndash Including PVRTrace and PVRTune
ndash wwwimgteccompowervrinsiderpowervr-utilitiesasp
54
developerandroidcomsdkndkGoogleGameDevAndroid
Feedback httpgooglNudVs
QampA
55
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdbgdb-rsp over named pipe
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdb
EclipseVS
gdb-rsp over named pipe
gdb-MI
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Important Tip
B)-36amp3)$$)J23
Bringing Your Game to Android
24
Devices Accessing Android Market
25
Android 16
Android 15
Android 23
Android 233
Android 30
Two Week Period Published May 2011
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
NativeActivity is just starting
ndash 43 of checking-in devices can utilize it
ndash For non-tablet-specific titles we can take advantage of NativeActivity without becoming incompatible
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Platform-specific Resources
Using NativeActivity Compatibly
27
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dV0WcQBII0d++++cBII0+81[8IRG58C6B64[dR69cQBII0dcQ6WI96Wd
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dR69cQBII0d++++cBII0+81[8IRG58C6B64[dV0WcQBII0dcQ6WI96Wd
Using NativeActivity Compatibly
28
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
cR5N5R2+846I54)81[Kgt$XR5N$R5N5R2[+++846I54)8B04[^BII0QRWRG58C6B64[d++c1R34R+846I54)81[846I54KLLK05B81[+++++846I54)N09[W8R5N[+Qd++++++++++++++++++++++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6d++++++++++++cQR5N5R2dcR5N5R2+846I54)81[K1I$R5N5R2[+++846I54)8B04[^BII0Q8IRG58C6B64[d++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6dcQR5N5R2d
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+W8R5N$F$Ggt+)+3$XltJXm$gtltFJgt+ )+C09R50WK+k+ LL3846I5438R5NK$JMgt+)+30GgtND+3040+300IC+30G+30846I54$gt$JJMlt$ltJgt+ )+846I548R5NLLC09$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7-00+51LI6R31I490a846I54Q8R5NLLC097
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
LTC+I1KY1L0KW88C0WU
L9B05+0WW+gt$XR5N$R5N5R2+YR84W+846I54KLLKXR5N$R5N5R2+Z
++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
LTC+I1KY1L0KW88C0WU
L9B05+0WW+1I$R5N5R2+YR84W+846I54KLLK$R5N5R2+Z++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++++++gt2WR1K0I45B662-[WE85[7U++++KKK
Key Game Components
33
Lifecycle
Graphics Sound
Input
Assets
Activity LifecycleLifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Process LifecycleLifecycle
Android keeps application processes around for as long as possible
ndash Even when the activity is closed with V585W`-7 or the back key is pressed
The foreground activity process is considered the most important
ndash It can still be killed as a last resort
Visible activities are also given high priority
ndash Backgrounded activities are considered less important
ndash Processes with no active activities are killed first
Implications of the Process LifecycleLifecycle
Be careful with static initializers
ndash Your library cannot be unloaded while your process is active
bull Donrsquot assume that your static initializers will be run when your activity is created
Be careful with threads
ndash Threads are tied to the process not the activity
bull Your threads will continue to run at reduced priority even if your activity is backgrounded or destroyed
ndash Gameplay should stop during onPause
bull It might make sense to keep certain threads running - your activity may still be visible
ndash Make sure all native code is cleaned up during onDestroy
bull Users expect that your application will no longer be active when its activity is destroyed
The Basics
Key handling
ndash Your device most likely has capacitive buttons
bull Look for complete state transitions of I8m2I_8I8m2AL
bull Avoid overriding 45WLR`m2N8R
ndash Use I8m290R5L0I8m2I8Camp6WW
bull Keep your game behaving like an Android application
TouchMultitouch handling
ndash With I8I9`N8R
bull take advantage of built-in gesture processing
ndash use gt0GWR96RRI6 and GWR96RRI6
ndash Most devices now support multitouch
bull determine if your device can track distinct points
ndash `Wgt2WR1FR96-F$AltA(gtltXAJA(JgtJX)
37
Input
Other Input
Trackball handling
ndash With I86TB00N8R
bull Unhandled events turn into dpad events
Motion handling
ndash With I8gt8WI6`8C4
bull Must be registered with the gt8WI68C6
bull Disable unneeded sensors especially when paused
ndash Active sensors will quickly drain the battery
38
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
OpenGL
GLSurfaceView
ndash Creates the compatible context
bull Contexts are shared between native code and Dalvik
ndash Creates a rendering thread
ndash Releases the context during onPause
ndash Not the most efficient way to multitask withOpenGL but it avoids some driver issues
When context is lost
ndash Reload resources
bull Textures
bull Buffer objects
bull Shaders
ndash Names donrsquot persist
40
Graphics
Texture Formats
Android encourages innovation in hardware
ndash Chipset vendors use several kinds of proprietary texture compression formats
ndash OpenGL ES supports multiple compressed formats none mandatory
Solutions
ndash Uncompressed Textures
ndash Use ETC1 ndash broad support in 20
bull Optimized around photographic data
bull No Alpha
ndash Use Multi-APK (coming soon)
ndash Put textures on an asset server
bull Detect support at runtime
bull Download to each device
41
Graphics
Drawing for Performance
Draw order is important
ndash Has no impact on some platforms means everything on others
ndash Draw front to back to make best use of early rejects
Use VBOs
ndash Avoid unnecessary state changes
Textures
ndash Use power of 2 sized textures
bull It can be very slow
bull On some chipsets not all address modes work
42
Graphics
Writing Compatible Shaders
Query query
ndash Make sure to query for number of attributes varying and uniforms supported
bull Varies between devices
bull Not respecting will make your application crash
bull ldquoSupportedrdquo does not mean ldquoperforms wellrdquo
Conditions
ndash Avoid as much as possible
bull if necessary put them last in the shader
ndash Use mix() clamp() etc to create the same result
discard()
ndash Avoid discard()
bull if necessary it should be last
43
Graphics
Audio Solutions
Full track audio
s 45amp026
bull Plays multiple formats with codec support
bull Plays from filesystem or from network
bull Has high latency memory and CPU usage for quick sound effects
Sound effects and clips
s gtI984ampII0
bull Plays multiple formats with codec support
bull Preloads audio files to a pool
ndash Plays them with low latency
44
Sound
Audio Solutions
Application-generated audio
s $945I6T
bull Plays PCM audio only with minimal latency
bull Useful for applications that wish to perform sound processing or mixing
OpenSLES
ndash Combines capabilities of 45amp026 and $945I6T
ndash Available only in the NDK
ndash Requires Android 23 and higher
45
Sound
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
Use native AssetManager
ndash Gingerbread and Beyond
Targeting tricky trying tasks
Troubleshooting Tips and Tricks
47
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
One JNI Context Per Thread
Threading Options
49
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
JNI Context 2
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
OR
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
If all else fails Market filters
ndash Instruction set
ndash ARMv5ARMv7
ndash GL version
ndash Platform release
ndash Use Device Availability
Tips Standing Out from the Crowd
Start Small
ndash Download assets as-needed
ndash Hook me early instead of making me wait
Use Android backuprestore service (save to the cloud)
ndash Keep my progress when I switch devices
Support multiple control schemes
ndash Trackball D-pad virtual stick
ndash Let me decide what works best
Support install-to-SD
ndash Android Market users will knock your ratings if you donrsquot
51
Tips Standing Out from the Crowd
Profiling
ndash In-game profiling to select optimal settings per-device
Social
ndash Hook into social networks
ndash Use OpenID
Build a live wallpaper
ndash Own the userrsquos home screen with stats avatars
Analytics
ndash Market and in-game
In-app payments
ndash Consider alternative monetization techniques
52
Troubleshooting Development Tools
NVIDIA Debug Manager for Eclipse
ndash Simplifies setup for native debugger under Eclipse
bull developernvidiacomtegranvidia-debug-manager-android-ndk
WinGDB
ndash Use Visual Studio to debug Android NDK applications
bull wwwwingdbcom
vs-android
ndash Native MSBuild files for Android toolchain
bull vs-androidgooglecodecom
53
Troubleshooting Performance Tools
NVIDIA PerfHUD ES
ndash developernvidiacomtegraperfhud-es
Adreno Profiler
ndash developerqualcommcomshowcaseadreno-profiler
POWERVR Insider Utilities
ndash Including PVRTrace and PVRTune
ndash wwwimgteccompowervrinsiderpowervr-utilitiesasp
54
developerandroidcomsdkndkGoogleGameDevAndroid
Feedback httpgooglNudVs
QampA
55
gt=0Alt3
ndash Sanity checks your setup
ndash Starts gdbserver on device opens named pipe
ndash Forwards pipe to socket on host
ndash Starts gdb client on host connects to socket
Host
Development Flow Debug
22
Device
gdbserver
application
gdb
EclipseVS
gdb-rsp over named pipe
gdb-MI
Set up project
Write interface classes
Write JNI glue
Write makefiles
Build Deploy
Debug
Important Tip
B)-36amp3)$$)J23
Bringing Your Game to Android
24
Devices Accessing Android Market
25
Android 16
Android 15
Android 23
Android 233
Android 30
Two Week Period Published May 2011
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
NativeActivity is just starting
ndash 43 of checking-in devices can utilize it
ndash For non-tablet-specific titles we can take advantage of NativeActivity without becoming incompatible
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Platform-specific Resources
Using NativeActivity Compatibly
27
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dV0WcQBII0d++++cBII0+81[8IRG58C6B64[dR69cQBII0dcQ6WI96Wd
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dR69cQBII0d++++cBII0+81[8IRG58C6B64[dV0WcQBII0dcQ6WI96Wd
Using NativeActivity Compatibly
28
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
cR5N5R2+846I54)81[Kgt$XR5N$R5N5R2[+++846I54)8B04[^BII0QRWRG58C6B64[d++c1R34R+846I54)81[846I54KLLK05B81[+++++846I54)N09[W8R5N[+Qd++++++++++++++++++++++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6d++++++++++++cQR5N5R2dcR5N5R2+846I54)81[K1I$R5N5R2[+++846I54)8B04[^BII0Q8IRG58C6B64[d++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6dcQR5N5R2d
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+W8R5N$F$Ggt+)+3$XltJXm$gtltFJgt+ )+C09R50WK+k+ LL3846I5438R5NK$JMgt+)+30GgtND+3040+300IC+30G+30846I54$gt$JJMlt$ltJgt+ )+846I548R5NLLC09$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7-00+51LI6R31I490a846I54Q8R5NLLC097
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
LTC+I1KY1L0KW88C0WU
L9B05+0WW+gt$XR5N$R5N5R2+YR84W+846I54KLLKXR5N$R5N5R2+Z
++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
LTC+I1KY1L0KW88C0WU
L9B05+0WW+1I$R5N5R2+YR84W+846I54KLLK$R5N5R2+Z++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++++++gt2WR1K0I45B662-[WE85[7U++++KKK
Key Game Components
33
Lifecycle
Graphics Sound
Input
Assets
Activity LifecycleLifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Process LifecycleLifecycle
Android keeps application processes around for as long as possible
ndash Even when the activity is closed with V585W`-7 or the back key is pressed
The foreground activity process is considered the most important
ndash It can still be killed as a last resort
Visible activities are also given high priority
ndash Backgrounded activities are considered less important
ndash Processes with no active activities are killed first
Implications of the Process LifecycleLifecycle
Be careful with static initializers
ndash Your library cannot be unloaded while your process is active
bull Donrsquot assume that your static initializers will be run when your activity is created
Be careful with threads
ndash Threads are tied to the process not the activity
bull Your threads will continue to run at reduced priority even if your activity is backgrounded or destroyed
ndash Gameplay should stop during onPause
bull It might make sense to keep certain threads running - your activity may still be visible
ndash Make sure all native code is cleaned up during onDestroy
bull Users expect that your application will no longer be active when its activity is destroyed
The Basics
Key handling
ndash Your device most likely has capacitive buttons
bull Look for complete state transitions of I8m2I_8I8m2AL
bull Avoid overriding 45WLR`m2N8R
ndash Use I8m290R5L0I8m2I8Camp6WW
bull Keep your game behaving like an Android application
TouchMultitouch handling
ndash With I8I9`N8R
bull take advantage of built-in gesture processing
ndash use gt0GWR96RRI6 and GWR96RRI6
ndash Most devices now support multitouch
bull determine if your device can track distinct points
ndash `Wgt2WR1FR96-F$AltA(gtltXAJA(JgtJX)
37
Input
Other Input
Trackball handling
ndash With I86TB00N8R
bull Unhandled events turn into dpad events
Motion handling
ndash With I8gt8WI6`8C4
bull Must be registered with the gt8WI68C6
bull Disable unneeded sensors especially when paused
ndash Active sensors will quickly drain the battery
38
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
OpenGL
GLSurfaceView
ndash Creates the compatible context
bull Contexts are shared between native code and Dalvik
ndash Creates a rendering thread
ndash Releases the context during onPause
ndash Not the most efficient way to multitask withOpenGL but it avoids some driver issues
When context is lost
ndash Reload resources
bull Textures
bull Buffer objects
bull Shaders
ndash Names donrsquot persist
40
Graphics
Texture Formats
Android encourages innovation in hardware
ndash Chipset vendors use several kinds of proprietary texture compression formats
ndash OpenGL ES supports multiple compressed formats none mandatory
Solutions
ndash Uncompressed Textures
ndash Use ETC1 ndash broad support in 20
bull Optimized around photographic data
bull No Alpha
ndash Use Multi-APK (coming soon)
ndash Put textures on an asset server
bull Detect support at runtime
bull Download to each device
41
Graphics
Drawing for Performance
Draw order is important
ndash Has no impact on some platforms means everything on others
ndash Draw front to back to make best use of early rejects
Use VBOs
ndash Avoid unnecessary state changes
Textures
ndash Use power of 2 sized textures
bull It can be very slow
bull On some chipsets not all address modes work
42
Graphics
Writing Compatible Shaders
Query query
ndash Make sure to query for number of attributes varying and uniforms supported
bull Varies between devices
bull Not respecting will make your application crash
bull ldquoSupportedrdquo does not mean ldquoperforms wellrdquo
Conditions
ndash Avoid as much as possible
bull if necessary put them last in the shader
ndash Use mix() clamp() etc to create the same result
discard()
ndash Avoid discard()
bull if necessary it should be last
43
Graphics
Audio Solutions
Full track audio
s 45amp026
bull Plays multiple formats with codec support
bull Plays from filesystem or from network
bull Has high latency memory and CPU usage for quick sound effects
Sound effects and clips
s gtI984ampII0
bull Plays multiple formats with codec support
bull Preloads audio files to a pool
ndash Plays them with low latency
44
Sound
Audio Solutions
Application-generated audio
s $945I6T
bull Plays PCM audio only with minimal latency
bull Useful for applications that wish to perform sound processing or mixing
OpenSLES
ndash Combines capabilities of 45amp026 and $945I6T
ndash Available only in the NDK
ndash Requires Android 23 and higher
45
Sound
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
Use native AssetManager
ndash Gingerbread and Beyond
Targeting tricky trying tasks
Troubleshooting Tips and Tricks
47
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
One JNI Context Per Thread
Threading Options
49
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
JNI Context 2
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
OR
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
If all else fails Market filters
ndash Instruction set
ndash ARMv5ARMv7
ndash GL version
ndash Platform release
ndash Use Device Availability
Tips Standing Out from the Crowd
Start Small
ndash Download assets as-needed
ndash Hook me early instead of making me wait
Use Android backuprestore service (save to the cloud)
ndash Keep my progress when I switch devices
Support multiple control schemes
ndash Trackball D-pad virtual stick
ndash Let me decide what works best
Support install-to-SD
ndash Android Market users will knock your ratings if you donrsquot
51
Tips Standing Out from the Crowd
Profiling
ndash In-game profiling to select optimal settings per-device
Social
ndash Hook into social networks
ndash Use OpenID
Build a live wallpaper
ndash Own the userrsquos home screen with stats avatars
Analytics
ndash Market and in-game
In-app payments
ndash Consider alternative monetization techniques
52
Troubleshooting Development Tools
NVIDIA Debug Manager for Eclipse
ndash Simplifies setup for native debugger under Eclipse
bull developernvidiacomtegranvidia-debug-manager-android-ndk
WinGDB
ndash Use Visual Studio to debug Android NDK applications
bull wwwwingdbcom
vs-android
ndash Native MSBuild files for Android toolchain
bull vs-androidgooglecodecom
53
Troubleshooting Performance Tools
NVIDIA PerfHUD ES
ndash developernvidiacomtegraperfhud-es
Adreno Profiler
ndash developerqualcommcomshowcaseadreno-profiler
POWERVR Insider Utilities
ndash Including PVRTrace and PVRTune
ndash wwwimgteccompowervrinsiderpowervr-utilitiesasp
54
developerandroidcomsdkndkGoogleGameDevAndroid
Feedback httpgooglNudVs
QampA
55
Important Tip
B)-36amp3)$$)J23
Bringing Your Game to Android
24
Devices Accessing Android Market
25
Android 16
Android 15
Android 23
Android 233
Android 30
Two Week Period Published May 2011
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
NativeActivity is just starting
ndash 43 of checking-in devices can utilize it
ndash For non-tablet-specific titles we can take advantage of NativeActivity without becoming incompatible
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Platform-specific Resources
Using NativeActivity Compatibly
27
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dV0WcQBII0d++++cBII0+81[8IRG58C6B64[dR69cQBII0dcQ6WI96Wd
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dR69cQBII0d++++cBII0+81[8IRG58C6B64[dV0WcQBII0dcQ6WI96Wd
Using NativeActivity Compatibly
28
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
cR5N5R2+846I54)81[Kgt$XR5N$R5N5R2[+++846I54)8B04[^BII0QRWRG58C6B64[d++c1R34R+846I54)81[846I54KLLK05B81[+++++846I54)N09[W8R5N[+Qd++++++++++++++++++++++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6d++++++++++++cQR5N5R2dcR5N5R2+846I54)81[K1I$R5N5R2[+++846I54)8B04[^BII0Q8IRG58C6B64[d++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6dcQR5N5R2d
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+W8R5N$F$Ggt+)+3$XltJXm$gtltFJgt+ )+C09R50WK+k+ LL3846I5438R5NK$JMgt+)+30GgtND+3040+300IC+30G+30846I54$gt$JJMlt$ltJgt+ )+846I548R5NLLC09$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7-00+51LI6R31I490a846I54Q8R5NLLC097
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
LTC+I1KY1L0KW88C0WU
L9B05+0WW+gt$XR5N$R5N5R2+YR84W+846I54KLLKXR5N$R5N5R2+Z
++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
LTC+I1KY1L0KW88C0WU
L9B05+0WW+1I$R5N5R2+YR84W+846I54KLLK$R5N5R2+Z++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++++++gt2WR1K0I45B662-[WE85[7U++++KKK
Key Game Components
33
Lifecycle
Graphics Sound
Input
Assets
Activity LifecycleLifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Process LifecycleLifecycle
Android keeps application processes around for as long as possible
ndash Even when the activity is closed with V585W`-7 or the back key is pressed
The foreground activity process is considered the most important
ndash It can still be killed as a last resort
Visible activities are also given high priority
ndash Backgrounded activities are considered less important
ndash Processes with no active activities are killed first
Implications of the Process LifecycleLifecycle
Be careful with static initializers
ndash Your library cannot be unloaded while your process is active
bull Donrsquot assume that your static initializers will be run when your activity is created
Be careful with threads
ndash Threads are tied to the process not the activity
bull Your threads will continue to run at reduced priority even if your activity is backgrounded or destroyed
ndash Gameplay should stop during onPause
bull It might make sense to keep certain threads running - your activity may still be visible
ndash Make sure all native code is cleaned up during onDestroy
bull Users expect that your application will no longer be active when its activity is destroyed
The Basics
Key handling
ndash Your device most likely has capacitive buttons
bull Look for complete state transitions of I8m2I_8I8m2AL
bull Avoid overriding 45WLR`m2N8R
ndash Use I8m290R5L0I8m2I8Camp6WW
bull Keep your game behaving like an Android application
TouchMultitouch handling
ndash With I8I9`N8R
bull take advantage of built-in gesture processing
ndash use gt0GWR96RRI6 and GWR96RRI6
ndash Most devices now support multitouch
bull determine if your device can track distinct points
ndash `Wgt2WR1FR96-F$AltA(gtltXAJA(JgtJX)
37
Input
Other Input
Trackball handling
ndash With I86TB00N8R
bull Unhandled events turn into dpad events
Motion handling
ndash With I8gt8WI6`8C4
bull Must be registered with the gt8WI68C6
bull Disable unneeded sensors especially when paused
ndash Active sensors will quickly drain the battery
38
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
OpenGL
GLSurfaceView
ndash Creates the compatible context
bull Contexts are shared between native code and Dalvik
ndash Creates a rendering thread
ndash Releases the context during onPause
ndash Not the most efficient way to multitask withOpenGL but it avoids some driver issues
When context is lost
ndash Reload resources
bull Textures
bull Buffer objects
bull Shaders
ndash Names donrsquot persist
40
Graphics
Texture Formats
Android encourages innovation in hardware
ndash Chipset vendors use several kinds of proprietary texture compression formats
ndash OpenGL ES supports multiple compressed formats none mandatory
Solutions
ndash Uncompressed Textures
ndash Use ETC1 ndash broad support in 20
bull Optimized around photographic data
bull No Alpha
ndash Use Multi-APK (coming soon)
ndash Put textures on an asset server
bull Detect support at runtime
bull Download to each device
41
Graphics
Drawing for Performance
Draw order is important
ndash Has no impact on some platforms means everything on others
ndash Draw front to back to make best use of early rejects
Use VBOs
ndash Avoid unnecessary state changes
Textures
ndash Use power of 2 sized textures
bull It can be very slow
bull On some chipsets not all address modes work
42
Graphics
Writing Compatible Shaders
Query query
ndash Make sure to query for number of attributes varying and uniforms supported
bull Varies between devices
bull Not respecting will make your application crash
bull ldquoSupportedrdquo does not mean ldquoperforms wellrdquo
Conditions
ndash Avoid as much as possible
bull if necessary put them last in the shader
ndash Use mix() clamp() etc to create the same result
discard()
ndash Avoid discard()
bull if necessary it should be last
43
Graphics
Audio Solutions
Full track audio
s 45amp026
bull Plays multiple formats with codec support
bull Plays from filesystem or from network
bull Has high latency memory and CPU usage for quick sound effects
Sound effects and clips
s gtI984ampII0
bull Plays multiple formats with codec support
bull Preloads audio files to a pool
ndash Plays them with low latency
44
Sound
Audio Solutions
Application-generated audio
s $945I6T
bull Plays PCM audio only with minimal latency
bull Useful for applications that wish to perform sound processing or mixing
OpenSLES
ndash Combines capabilities of 45amp026 and $945I6T
ndash Available only in the NDK
ndash Requires Android 23 and higher
45
Sound
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
Use native AssetManager
ndash Gingerbread and Beyond
Targeting tricky trying tasks
Troubleshooting Tips and Tricks
47
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
One JNI Context Per Thread
Threading Options
49
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
JNI Context 2
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
OR
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
If all else fails Market filters
ndash Instruction set
ndash ARMv5ARMv7
ndash GL version
ndash Platform release
ndash Use Device Availability
Tips Standing Out from the Crowd
Start Small
ndash Download assets as-needed
ndash Hook me early instead of making me wait
Use Android backuprestore service (save to the cloud)
ndash Keep my progress when I switch devices
Support multiple control schemes
ndash Trackball D-pad virtual stick
ndash Let me decide what works best
Support install-to-SD
ndash Android Market users will knock your ratings if you donrsquot
51
Tips Standing Out from the Crowd
Profiling
ndash In-game profiling to select optimal settings per-device
Social
ndash Hook into social networks
ndash Use OpenID
Build a live wallpaper
ndash Own the userrsquos home screen with stats avatars
Analytics
ndash Market and in-game
In-app payments
ndash Consider alternative monetization techniques
52
Troubleshooting Development Tools
NVIDIA Debug Manager for Eclipse
ndash Simplifies setup for native debugger under Eclipse
bull developernvidiacomtegranvidia-debug-manager-android-ndk
WinGDB
ndash Use Visual Studio to debug Android NDK applications
bull wwwwingdbcom
vs-android
ndash Native MSBuild files for Android toolchain
bull vs-androidgooglecodecom
53
Troubleshooting Performance Tools
NVIDIA PerfHUD ES
ndash developernvidiacomtegraperfhud-es
Adreno Profiler
ndash developerqualcommcomshowcaseadreno-profiler
POWERVR Insider Utilities
ndash Including PVRTrace and PVRTune
ndash wwwimgteccompowervrinsiderpowervr-utilitiesasp
54
developerandroidcomsdkndkGoogleGameDevAndroid
Feedback httpgooglNudVs
QampA
55
Bringing Your Game to Android
24
Devices Accessing Android Market
25
Android 16
Android 15
Android 23
Android 233
Android 30
Two Week Period Published May 2011
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
NativeActivity is just starting
ndash 43 of checking-in devices can utilize it
ndash For non-tablet-specific titles we can take advantage of NativeActivity without becoming incompatible
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Platform-specific Resources
Using NativeActivity Compatibly
27
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dV0WcQBII0d++++cBII0+81[8IRG58C6B64[dR69cQBII0dcQ6WI96Wd
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dR69cQBII0d++++cBII0+81[8IRG58C6B64[dV0WcQBII0dcQ6WI96Wd
Using NativeActivity Compatibly
28
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
cR5N5R2+846I54)81[Kgt$XR5N$R5N5R2[+++846I54)8B04[^BII0QRWRG58C6B64[d++c1R34R+846I54)81[846I54KLLK05B81[+++++846I54)N09[W8R5N[+Qd++++++++++++++++++++++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6d++++++++++++cQR5N5R2dcR5N5R2+846I54)81[K1I$R5N5R2[+++846I54)8B04[^BII0Q8IRG58C6B64[d++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6dcQR5N5R2d
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+W8R5N$F$Ggt+)+3$XltJXm$gtltFJgt+ )+C09R50WK+k+ LL3846I5438R5NK$JMgt+)+30GgtND+3040+300IC+30G+30846I54$gt$JJMlt$ltJgt+ )+846I548R5NLLC09$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7-00+51LI6R31I490a846I54Q8R5NLLC097
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
LTC+I1KY1L0KW88C0WU
L9B05+0WW+gt$XR5N$R5N5R2+YR84W+846I54KLLKXR5N$R5N5R2+Z
++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
LTC+I1KY1L0KW88C0WU
L9B05+0WW+1I$R5N5R2+YR84W+846I54KLLK$R5N5R2+Z++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++++++gt2WR1K0I45B662-[WE85[7U++++KKK
Key Game Components
33
Lifecycle
Graphics Sound
Input
Assets
Activity LifecycleLifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Process LifecycleLifecycle
Android keeps application processes around for as long as possible
ndash Even when the activity is closed with V585W`-7 or the back key is pressed
The foreground activity process is considered the most important
ndash It can still be killed as a last resort
Visible activities are also given high priority
ndash Backgrounded activities are considered less important
ndash Processes with no active activities are killed first
Implications of the Process LifecycleLifecycle
Be careful with static initializers
ndash Your library cannot be unloaded while your process is active
bull Donrsquot assume that your static initializers will be run when your activity is created
Be careful with threads
ndash Threads are tied to the process not the activity
bull Your threads will continue to run at reduced priority even if your activity is backgrounded or destroyed
ndash Gameplay should stop during onPause
bull It might make sense to keep certain threads running - your activity may still be visible
ndash Make sure all native code is cleaned up during onDestroy
bull Users expect that your application will no longer be active when its activity is destroyed
The Basics
Key handling
ndash Your device most likely has capacitive buttons
bull Look for complete state transitions of I8m2I_8I8m2AL
bull Avoid overriding 45WLR`m2N8R
ndash Use I8m290R5L0I8m2I8Camp6WW
bull Keep your game behaving like an Android application
TouchMultitouch handling
ndash With I8I9`N8R
bull take advantage of built-in gesture processing
ndash use gt0GWR96RRI6 and GWR96RRI6
ndash Most devices now support multitouch
bull determine if your device can track distinct points
ndash `Wgt2WR1FR96-F$AltA(gtltXAJA(JgtJX)
37
Input
Other Input
Trackball handling
ndash With I86TB00N8R
bull Unhandled events turn into dpad events
Motion handling
ndash With I8gt8WI6`8C4
bull Must be registered with the gt8WI68C6
bull Disable unneeded sensors especially when paused
ndash Active sensors will quickly drain the battery
38
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
OpenGL
GLSurfaceView
ndash Creates the compatible context
bull Contexts are shared between native code and Dalvik
ndash Creates a rendering thread
ndash Releases the context during onPause
ndash Not the most efficient way to multitask withOpenGL but it avoids some driver issues
When context is lost
ndash Reload resources
bull Textures
bull Buffer objects
bull Shaders
ndash Names donrsquot persist
40
Graphics
Texture Formats
Android encourages innovation in hardware
ndash Chipset vendors use several kinds of proprietary texture compression formats
ndash OpenGL ES supports multiple compressed formats none mandatory
Solutions
ndash Uncompressed Textures
ndash Use ETC1 ndash broad support in 20
bull Optimized around photographic data
bull No Alpha
ndash Use Multi-APK (coming soon)
ndash Put textures on an asset server
bull Detect support at runtime
bull Download to each device
41
Graphics
Drawing for Performance
Draw order is important
ndash Has no impact on some platforms means everything on others
ndash Draw front to back to make best use of early rejects
Use VBOs
ndash Avoid unnecessary state changes
Textures
ndash Use power of 2 sized textures
bull It can be very slow
bull On some chipsets not all address modes work
42
Graphics
Writing Compatible Shaders
Query query
ndash Make sure to query for number of attributes varying and uniforms supported
bull Varies between devices
bull Not respecting will make your application crash
bull ldquoSupportedrdquo does not mean ldquoperforms wellrdquo
Conditions
ndash Avoid as much as possible
bull if necessary put them last in the shader
ndash Use mix() clamp() etc to create the same result
discard()
ndash Avoid discard()
bull if necessary it should be last
43
Graphics
Audio Solutions
Full track audio
s 45amp026
bull Plays multiple formats with codec support
bull Plays from filesystem or from network
bull Has high latency memory and CPU usage for quick sound effects
Sound effects and clips
s gtI984ampII0
bull Plays multiple formats with codec support
bull Preloads audio files to a pool
ndash Plays them with low latency
44
Sound
Audio Solutions
Application-generated audio
s $945I6T
bull Plays PCM audio only with minimal latency
bull Useful for applications that wish to perform sound processing or mixing
OpenSLES
ndash Combines capabilities of 45amp026 and $945I6T
ndash Available only in the NDK
ndash Requires Android 23 and higher
45
Sound
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
Use native AssetManager
ndash Gingerbread and Beyond
Targeting tricky trying tasks
Troubleshooting Tips and Tricks
47
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
One JNI Context Per Thread
Threading Options
49
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
JNI Context 2
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
OR
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
If all else fails Market filters
ndash Instruction set
ndash ARMv5ARMv7
ndash GL version
ndash Platform release
ndash Use Device Availability
Tips Standing Out from the Crowd
Start Small
ndash Download assets as-needed
ndash Hook me early instead of making me wait
Use Android backuprestore service (save to the cloud)
ndash Keep my progress when I switch devices
Support multiple control schemes
ndash Trackball D-pad virtual stick
ndash Let me decide what works best
Support install-to-SD
ndash Android Market users will knock your ratings if you donrsquot
51
Tips Standing Out from the Crowd
Profiling
ndash In-game profiling to select optimal settings per-device
Social
ndash Hook into social networks
ndash Use OpenID
Build a live wallpaper
ndash Own the userrsquos home screen with stats avatars
Analytics
ndash Market and in-game
In-app payments
ndash Consider alternative monetization techniques
52
Troubleshooting Development Tools
NVIDIA Debug Manager for Eclipse
ndash Simplifies setup for native debugger under Eclipse
bull developernvidiacomtegranvidia-debug-manager-android-ndk
WinGDB
ndash Use Visual Studio to debug Android NDK applications
bull wwwwingdbcom
vs-android
ndash Native MSBuild files for Android toolchain
bull vs-androidgooglecodecom
53
Troubleshooting Performance Tools
NVIDIA PerfHUD ES
ndash developernvidiacomtegraperfhud-es
Adreno Profiler
ndash developerqualcommcomshowcaseadreno-profiler
POWERVR Insider Utilities
ndash Including PVRTrace and PVRTune
ndash wwwimgteccompowervrinsiderpowervr-utilitiesasp
54
developerandroidcomsdkndkGoogleGameDevAndroid
Feedback httpgooglNudVs
QampA
55
Devices Accessing Android Market
25
Android 16
Android 15
Android 23
Android 233
Android 30
Two Week Period Published May 2011
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
NativeActivity is just starting
ndash 43 of checking-in devices can utilize it
ndash For non-tablet-specific titles we can take advantage of NativeActivity without becoming incompatible
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Platform-specific Resources
Using NativeActivity Compatibly
27
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dV0WcQBII0d++++cBII0+81[8IRG58C6B64[dR69cQBII0dcQ6WI96Wd
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dR69cQBII0d++++cBII0+81[8IRG58C6B64[dV0WcQBII0dcQ6WI96Wd
Using NativeActivity Compatibly
28
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
cR5N5R2+846I54)81[Kgt$XR5N$R5N5R2[+++846I54)8B04[^BII0QRWRG58C6B64[d++c1R34R+846I54)81[846I54KLLK05B81[+++++846I54)N09[W8R5N[+Qd++++++++++++++++++++++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6d++++++++++++cQR5N5R2dcR5N5R2+846I54)81[K1I$R5N5R2[+++846I54)8B04[^BII0Q8IRG58C6B64[d++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6dcQR5N5R2d
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+W8R5N$F$Ggt+)+3$XltJXm$gtltFJgt+ )+C09R50WK+k+ LL3846I5438R5NK$JMgt+)+30GgtND+3040+300IC+30G+30846I54$gt$JJMlt$ltJgt+ )+846I548R5NLLC09$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7-00+51LI6R31I490a846I54Q8R5NLLC097
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
LTC+I1KY1L0KW88C0WU
L9B05+0WW+gt$XR5N$R5N5R2+YR84W+846I54KLLKXR5N$R5N5R2+Z
++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
LTC+I1KY1L0KW88C0WU
L9B05+0WW+1I$R5N5R2+YR84W+846I54KLLK$R5N5R2+Z++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++++++gt2WR1K0I45B662-[WE85[7U++++KKK
Key Game Components
33
Lifecycle
Graphics Sound
Input
Assets
Activity LifecycleLifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Process LifecycleLifecycle
Android keeps application processes around for as long as possible
ndash Even when the activity is closed with V585W`-7 or the back key is pressed
The foreground activity process is considered the most important
ndash It can still be killed as a last resort
Visible activities are also given high priority
ndash Backgrounded activities are considered less important
ndash Processes with no active activities are killed first
Implications of the Process LifecycleLifecycle
Be careful with static initializers
ndash Your library cannot be unloaded while your process is active
bull Donrsquot assume that your static initializers will be run when your activity is created
Be careful with threads
ndash Threads are tied to the process not the activity
bull Your threads will continue to run at reduced priority even if your activity is backgrounded or destroyed
ndash Gameplay should stop during onPause
bull It might make sense to keep certain threads running - your activity may still be visible
ndash Make sure all native code is cleaned up during onDestroy
bull Users expect that your application will no longer be active when its activity is destroyed
The Basics
Key handling
ndash Your device most likely has capacitive buttons
bull Look for complete state transitions of I8m2I_8I8m2AL
bull Avoid overriding 45WLR`m2N8R
ndash Use I8m290R5L0I8m2I8Camp6WW
bull Keep your game behaving like an Android application
TouchMultitouch handling
ndash With I8I9`N8R
bull take advantage of built-in gesture processing
ndash use gt0GWR96RRI6 and GWR96RRI6
ndash Most devices now support multitouch
bull determine if your device can track distinct points
ndash `Wgt2WR1FR96-F$AltA(gtltXAJA(JgtJX)
37
Input
Other Input
Trackball handling
ndash With I86TB00N8R
bull Unhandled events turn into dpad events
Motion handling
ndash With I8gt8WI6`8C4
bull Must be registered with the gt8WI68C6
bull Disable unneeded sensors especially when paused
ndash Active sensors will quickly drain the battery
38
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
OpenGL
GLSurfaceView
ndash Creates the compatible context
bull Contexts are shared between native code and Dalvik
ndash Creates a rendering thread
ndash Releases the context during onPause
ndash Not the most efficient way to multitask withOpenGL but it avoids some driver issues
When context is lost
ndash Reload resources
bull Textures
bull Buffer objects
bull Shaders
ndash Names donrsquot persist
40
Graphics
Texture Formats
Android encourages innovation in hardware
ndash Chipset vendors use several kinds of proprietary texture compression formats
ndash OpenGL ES supports multiple compressed formats none mandatory
Solutions
ndash Uncompressed Textures
ndash Use ETC1 ndash broad support in 20
bull Optimized around photographic data
bull No Alpha
ndash Use Multi-APK (coming soon)
ndash Put textures on an asset server
bull Detect support at runtime
bull Download to each device
41
Graphics
Drawing for Performance
Draw order is important
ndash Has no impact on some platforms means everything on others
ndash Draw front to back to make best use of early rejects
Use VBOs
ndash Avoid unnecessary state changes
Textures
ndash Use power of 2 sized textures
bull It can be very slow
bull On some chipsets not all address modes work
42
Graphics
Writing Compatible Shaders
Query query
ndash Make sure to query for number of attributes varying and uniforms supported
bull Varies between devices
bull Not respecting will make your application crash
bull ldquoSupportedrdquo does not mean ldquoperforms wellrdquo
Conditions
ndash Avoid as much as possible
bull if necessary put them last in the shader
ndash Use mix() clamp() etc to create the same result
discard()
ndash Avoid discard()
bull if necessary it should be last
43
Graphics
Audio Solutions
Full track audio
s 45amp026
bull Plays multiple formats with codec support
bull Plays from filesystem or from network
bull Has high latency memory and CPU usage for quick sound effects
Sound effects and clips
s gtI984ampII0
bull Plays multiple formats with codec support
bull Preloads audio files to a pool
ndash Plays them with low latency
44
Sound
Audio Solutions
Application-generated audio
s $945I6T
bull Plays PCM audio only with minimal latency
bull Useful for applications that wish to perform sound processing or mixing
OpenSLES
ndash Combines capabilities of 45amp026 and $945I6T
ndash Available only in the NDK
ndash Requires Android 23 and higher
45
Sound
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
Use native AssetManager
ndash Gingerbread and Beyond
Targeting tricky trying tasks
Troubleshooting Tips and Tricks
47
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
One JNI Context Per Thread
Threading Options
49
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
JNI Context 2
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
OR
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
If all else fails Market filters
ndash Instruction set
ndash ARMv5ARMv7
ndash GL version
ndash Platform release
ndash Use Device Availability
Tips Standing Out from the Crowd
Start Small
ndash Download assets as-needed
ndash Hook me early instead of making me wait
Use Android backuprestore service (save to the cloud)
ndash Keep my progress when I switch devices
Support multiple control schemes
ndash Trackball D-pad virtual stick
ndash Let me decide what works best
Support install-to-SD
ndash Android Market users will knock your ratings if you donrsquot
51
Tips Standing Out from the Crowd
Profiling
ndash In-game profiling to select optimal settings per-device
Social
ndash Hook into social networks
ndash Use OpenID
Build a live wallpaper
ndash Own the userrsquos home screen with stats avatars
Analytics
ndash Market and in-game
In-app payments
ndash Consider alternative monetization techniques
52
Troubleshooting Development Tools
NVIDIA Debug Manager for Eclipse
ndash Simplifies setup for native debugger under Eclipse
bull developernvidiacomtegranvidia-debug-manager-android-ndk
WinGDB
ndash Use Visual Studio to debug Android NDK applications
bull wwwwingdbcom
vs-android
ndash Native MSBuild files for Android toolchain
bull vs-androidgooglecodecom
53
Troubleshooting Performance Tools
NVIDIA PerfHUD ES
ndash developernvidiacomtegraperfhud-es
Adreno Profiler
ndash developerqualcommcomshowcaseadreno-profiler
POWERVR Insider Utilities
ndash Including PVRTrace and PVRTune
ndash wwwimgteccompowervrinsiderpowervr-utilitiesasp
54
developerandroidcomsdkndkGoogleGameDevAndroid
Feedback httpgooglNudVs
QampA
55
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
NativeActivity is just starting
ndash 43 of checking-in devices can utilize it
ndash For non-tablet-specific titles we can take advantage of NativeActivity without becoming incompatible
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Platform-specific Resources
Using NativeActivity Compatibly
27
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dV0WcQBII0d++++cBII0+81[8IRG58C6B64[dR69cQBII0dcQ6WI96Wd
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dR69cQBII0d++++cBII0+81[8IRG58C6B64[dV0WcQBII0dcQ6WI96Wd
Using NativeActivity Compatibly
28
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
cR5N5R2+846I54)81[Kgt$XR5N$R5N5R2[+++846I54)8B04[^BII0QRWRG58C6B64[d++c1R34R+846I54)81[846I54KLLK05B81[+++++846I54)N09[W8R5N[+Qd++++++++++++++++++++++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6d++++++++++++cQR5N5R2dcR5N5R2+846I54)81[K1I$R5N5R2[+++846I54)8B04[^BII0Q8IRG58C6B64[d++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6dcQR5N5R2d
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+W8R5N$F$Ggt+)+3$XltJXm$gtltFJgt+ )+C09R50WK+k+ LL3846I5438R5NK$JMgt+)+30GgtND+3040+300IC+30G+30846I54$gt$JJMlt$ltJgt+ )+846I548R5NLLC09$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7-00+51LI6R31I490a846I54Q8R5NLLC097
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
LTC+I1KY1L0KW88C0WU
L9B05+0WW+gt$XR5N$R5N5R2+YR84W+846I54KLLKXR5N$R5N5R2+Z
++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
LTC+I1KY1L0KW88C0WU
L9B05+0WW+1I$R5N5R2+YR84W+846I54KLLK$R5N5R2+Z++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++++++gt2WR1K0I45B662-[WE85[7U++++KKK
Key Game Components
33
Lifecycle
Graphics Sound
Input
Assets
Activity LifecycleLifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Process LifecycleLifecycle
Android keeps application processes around for as long as possible
ndash Even when the activity is closed with V585W`-7 or the back key is pressed
The foreground activity process is considered the most important
ndash It can still be killed as a last resort
Visible activities are also given high priority
ndash Backgrounded activities are considered less important
ndash Processes with no active activities are killed first
Implications of the Process LifecycleLifecycle
Be careful with static initializers
ndash Your library cannot be unloaded while your process is active
bull Donrsquot assume that your static initializers will be run when your activity is created
Be careful with threads
ndash Threads are tied to the process not the activity
bull Your threads will continue to run at reduced priority even if your activity is backgrounded or destroyed
ndash Gameplay should stop during onPause
bull It might make sense to keep certain threads running - your activity may still be visible
ndash Make sure all native code is cleaned up during onDestroy
bull Users expect that your application will no longer be active when its activity is destroyed
The Basics
Key handling
ndash Your device most likely has capacitive buttons
bull Look for complete state transitions of I8m2I_8I8m2AL
bull Avoid overriding 45WLR`m2N8R
ndash Use I8m290R5L0I8m2I8Camp6WW
bull Keep your game behaving like an Android application
TouchMultitouch handling
ndash With I8I9`N8R
bull take advantage of built-in gesture processing
ndash use gt0GWR96RRI6 and GWR96RRI6
ndash Most devices now support multitouch
bull determine if your device can track distinct points
ndash `Wgt2WR1FR96-F$AltA(gtltXAJA(JgtJX)
37
Input
Other Input
Trackball handling
ndash With I86TB00N8R
bull Unhandled events turn into dpad events
Motion handling
ndash With I8gt8WI6`8C4
bull Must be registered with the gt8WI68C6
bull Disable unneeded sensors especially when paused
ndash Active sensors will quickly drain the battery
38
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
OpenGL
GLSurfaceView
ndash Creates the compatible context
bull Contexts are shared between native code and Dalvik
ndash Creates a rendering thread
ndash Releases the context during onPause
ndash Not the most efficient way to multitask withOpenGL but it avoids some driver issues
When context is lost
ndash Reload resources
bull Textures
bull Buffer objects
bull Shaders
ndash Names donrsquot persist
40
Graphics
Texture Formats
Android encourages innovation in hardware
ndash Chipset vendors use several kinds of proprietary texture compression formats
ndash OpenGL ES supports multiple compressed formats none mandatory
Solutions
ndash Uncompressed Textures
ndash Use ETC1 ndash broad support in 20
bull Optimized around photographic data
bull No Alpha
ndash Use Multi-APK (coming soon)
ndash Put textures on an asset server
bull Detect support at runtime
bull Download to each device
41
Graphics
Drawing for Performance
Draw order is important
ndash Has no impact on some platforms means everything on others
ndash Draw front to back to make best use of early rejects
Use VBOs
ndash Avoid unnecessary state changes
Textures
ndash Use power of 2 sized textures
bull It can be very slow
bull On some chipsets not all address modes work
42
Graphics
Writing Compatible Shaders
Query query
ndash Make sure to query for number of attributes varying and uniforms supported
bull Varies between devices
bull Not respecting will make your application crash
bull ldquoSupportedrdquo does not mean ldquoperforms wellrdquo
Conditions
ndash Avoid as much as possible
bull if necessary put them last in the shader
ndash Use mix() clamp() etc to create the same result
discard()
ndash Avoid discard()
bull if necessary it should be last
43
Graphics
Audio Solutions
Full track audio
s 45amp026
bull Plays multiple formats with codec support
bull Plays from filesystem or from network
bull Has high latency memory and CPU usage for quick sound effects
Sound effects and clips
s gtI984ampII0
bull Plays multiple formats with codec support
bull Preloads audio files to a pool
ndash Plays them with low latency
44
Sound
Audio Solutions
Application-generated audio
s $945I6T
bull Plays PCM audio only with minimal latency
bull Useful for applications that wish to perform sound processing or mixing
OpenSLES
ndash Combines capabilities of 45amp026 and $945I6T
ndash Available only in the NDK
ndash Requires Android 23 and higher
45
Sound
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
Use native AssetManager
ndash Gingerbread and Beyond
Targeting tricky trying tasks
Troubleshooting Tips and Tricks
47
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
One JNI Context Per Thread
Threading Options
49
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
JNI Context 2
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
OR
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
If all else fails Market filters
ndash Instruction set
ndash ARMv5ARMv7
ndash GL version
ndash Platform release
ndash Use Device Availability
Tips Standing Out from the Crowd
Start Small
ndash Download assets as-needed
ndash Hook me early instead of making me wait
Use Android backuprestore service (save to the cloud)
ndash Keep my progress when I switch devices
Support multiple control schemes
ndash Trackball D-pad virtual stick
ndash Let me decide what works best
Support install-to-SD
ndash Android Market users will knock your ratings if you donrsquot
51
Tips Standing Out from the Crowd
Profiling
ndash In-game profiling to select optimal settings per-device
Social
ndash Hook into social networks
ndash Use OpenID
Build a live wallpaper
ndash Own the userrsquos home screen with stats avatars
Analytics
ndash Market and in-game
In-app payments
ndash Consider alternative monetization techniques
52
Troubleshooting Development Tools
NVIDIA Debug Manager for Eclipse
ndash Simplifies setup for native debugger under Eclipse
bull developernvidiacomtegranvidia-debug-manager-android-ndk
WinGDB
ndash Use Visual Studio to debug Android NDK applications
bull wwwwingdbcom
vs-android
ndash Native MSBuild files for Android toolchain
bull vs-androidgooglecodecom
53
Troubleshooting Performance Tools
NVIDIA PerfHUD ES
ndash developernvidiacomtegraperfhud-es
Adreno Profiler
ndash developerqualcommcomshowcaseadreno-profiler
POWERVR Insider Utilities
ndash Including PVRTrace and PVRTune
ndash wwwimgteccompowervrinsiderpowervr-utilitiesasp
54
developerandroidcomsdkndkGoogleGameDevAndroid
Feedback httpgooglNudVs
QampA
55
Great uptake for Android 22
ndash In ten months 659 of devices checking in to Market running Froyo
ndash 947 of devices running Android 21 or higher
NativeActivity is just starting
ndash 43 of checking-in devices can utilize it
ndash For non-tablet-specific titles we can take advantage of NativeActivity without becoming incompatible
Devices Accessing Android Market
25
Android 22(Froyo)
Android 21(Eclair)
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Platform-specific Resources
Using NativeActivity Compatibly
27
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dV0WcQBII0d++++cBII0+81[8IRG58C6B64[dR69cQBII0dcQ6WI96Wd
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dR69cQBII0d++++cBII0+81[8IRG58C6B64[dV0WcQBII0dcQ6WI96Wd
Using NativeActivity Compatibly
28
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
cR5N5R2+846I54)81[Kgt$XR5N$R5N5R2[+++846I54)8B04[^BII0QRWRG58C6B64[d++c1R34R+846I54)81[846I54KLLK05B81[+++++846I54)N09[W8R5N[+Qd++++++++++++++++++++++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6d++++++++++++cQR5N5R2dcR5N5R2+846I54)81[K1I$R5N5R2[+++846I54)8B04[^BII0Q8IRG58C6B64[d++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6dcQR5N5R2d
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+W8R5N$F$Ggt+)+3$XltJXm$gtltFJgt+ )+C09R50WK+k+ LL3846I5438R5NK$JMgt+)+30GgtND+3040+300IC+30G+30846I54$gt$JJMlt$ltJgt+ )+846I548R5NLLC09$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7-00+51LI6R31I490a846I54Q8R5NLLC097
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
LTC+I1KY1L0KW88C0WU
L9B05+0WW+gt$XR5N$R5N5R2+YR84W+846I54KLLKXR5N$R5N5R2+Z
++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
LTC+I1KY1L0KW88C0WU
L9B05+0WW+1I$R5N5R2+YR84W+846I54KLLK$R5N5R2+Z++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++++++gt2WR1K0I45B662-[WE85[7U++++KKK
Key Game Components
33
Lifecycle
Graphics Sound
Input
Assets
Activity LifecycleLifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Process LifecycleLifecycle
Android keeps application processes around for as long as possible
ndash Even when the activity is closed with V585W`-7 or the back key is pressed
The foreground activity process is considered the most important
ndash It can still be killed as a last resort
Visible activities are also given high priority
ndash Backgrounded activities are considered less important
ndash Processes with no active activities are killed first
Implications of the Process LifecycleLifecycle
Be careful with static initializers
ndash Your library cannot be unloaded while your process is active
bull Donrsquot assume that your static initializers will be run when your activity is created
Be careful with threads
ndash Threads are tied to the process not the activity
bull Your threads will continue to run at reduced priority even if your activity is backgrounded or destroyed
ndash Gameplay should stop during onPause
bull It might make sense to keep certain threads running - your activity may still be visible
ndash Make sure all native code is cleaned up during onDestroy
bull Users expect that your application will no longer be active when its activity is destroyed
The Basics
Key handling
ndash Your device most likely has capacitive buttons
bull Look for complete state transitions of I8m2I_8I8m2AL
bull Avoid overriding 45WLR`m2N8R
ndash Use I8m290R5L0I8m2I8Camp6WW
bull Keep your game behaving like an Android application
TouchMultitouch handling
ndash With I8I9`N8R
bull take advantage of built-in gesture processing
ndash use gt0GWR96RRI6 and GWR96RRI6
ndash Most devices now support multitouch
bull determine if your device can track distinct points
ndash `Wgt2WR1FR96-F$AltA(gtltXAJA(JgtJX)
37
Input
Other Input
Trackball handling
ndash With I86TB00N8R
bull Unhandled events turn into dpad events
Motion handling
ndash With I8gt8WI6`8C4
bull Must be registered with the gt8WI68C6
bull Disable unneeded sensors especially when paused
ndash Active sensors will quickly drain the battery
38
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
OpenGL
GLSurfaceView
ndash Creates the compatible context
bull Contexts are shared between native code and Dalvik
ndash Creates a rendering thread
ndash Releases the context during onPause
ndash Not the most efficient way to multitask withOpenGL but it avoids some driver issues
When context is lost
ndash Reload resources
bull Textures
bull Buffer objects
bull Shaders
ndash Names donrsquot persist
40
Graphics
Texture Formats
Android encourages innovation in hardware
ndash Chipset vendors use several kinds of proprietary texture compression formats
ndash OpenGL ES supports multiple compressed formats none mandatory
Solutions
ndash Uncompressed Textures
ndash Use ETC1 ndash broad support in 20
bull Optimized around photographic data
bull No Alpha
ndash Use Multi-APK (coming soon)
ndash Put textures on an asset server
bull Detect support at runtime
bull Download to each device
41
Graphics
Drawing for Performance
Draw order is important
ndash Has no impact on some platforms means everything on others
ndash Draw front to back to make best use of early rejects
Use VBOs
ndash Avoid unnecessary state changes
Textures
ndash Use power of 2 sized textures
bull It can be very slow
bull On some chipsets not all address modes work
42
Graphics
Writing Compatible Shaders
Query query
ndash Make sure to query for number of attributes varying and uniforms supported
bull Varies between devices
bull Not respecting will make your application crash
bull ldquoSupportedrdquo does not mean ldquoperforms wellrdquo
Conditions
ndash Avoid as much as possible
bull if necessary put them last in the shader
ndash Use mix() clamp() etc to create the same result
discard()
ndash Avoid discard()
bull if necessary it should be last
43
Graphics
Audio Solutions
Full track audio
s 45amp026
bull Plays multiple formats with codec support
bull Plays from filesystem or from network
bull Has high latency memory and CPU usage for quick sound effects
Sound effects and clips
s gtI984ampII0
bull Plays multiple formats with codec support
bull Preloads audio files to a pool
ndash Plays them with low latency
44
Sound
Audio Solutions
Application-generated audio
s $945I6T
bull Plays PCM audio only with minimal latency
bull Useful for applications that wish to perform sound processing or mixing
OpenSLES
ndash Combines capabilities of 45amp026 and $945I6T
ndash Available only in the NDK
ndash Requires Android 23 and higher
45
Sound
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
Use native AssetManager
ndash Gingerbread and Beyond
Targeting tricky trying tasks
Troubleshooting Tips and Tricks
47
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
One JNI Context Per Thread
Threading Options
49
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
JNI Context 2
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
OR
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
If all else fails Market filters
ndash Instruction set
ndash ARMv5ARMv7
ndash GL version
ndash Platform release
ndash Use Device Availability
Tips Standing Out from the Crowd
Start Small
ndash Download assets as-needed
ndash Hook me early instead of making me wait
Use Android backuprestore service (save to the cloud)
ndash Keep my progress when I switch devices
Support multiple control schemes
ndash Trackball D-pad virtual stick
ndash Let me decide what works best
Support install-to-SD
ndash Android Market users will knock your ratings if you donrsquot
51
Tips Standing Out from the Crowd
Profiling
ndash In-game profiling to select optimal settings per-device
Social
ndash Hook into social networks
ndash Use OpenID
Build a live wallpaper
ndash Own the userrsquos home screen with stats avatars
Analytics
ndash Market and in-game
In-app payments
ndash Consider alternative monetization techniques
52
Troubleshooting Development Tools
NVIDIA Debug Manager for Eclipse
ndash Simplifies setup for native debugger under Eclipse
bull developernvidiacomtegranvidia-debug-manager-android-ndk
WinGDB
ndash Use Visual Studio to debug Android NDK applications
bull wwwwingdbcom
vs-android
ndash Native MSBuild files for Android toolchain
bull vs-androidgooglecodecom
53
Troubleshooting Performance Tools
NVIDIA PerfHUD ES
ndash developernvidiacomtegraperfhud-es
Adreno Profiler
ndash developerqualcommcomshowcaseadreno-profiler
POWERVR Insider Utilities
ndash Including PVRTrace and PVRTune
ndash wwwimgteccompowervrinsiderpowervr-utilitiesasp
54
developerandroidcomsdkndkGoogleGameDevAndroid
Feedback httpgooglNudVs
QampA
55
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Platform-specific Resources
Using NativeActivity Compatibly
27
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dV0WcQBII0d++++cBII0+81[8IRG58C6B64[dR69cQBII0dcQ6WI96Wd
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dR69cQBII0d++++cBII0+81[8IRG58C6B64[dV0WcQBII0dcQ6WI96Wd
Using NativeActivity Compatibly
28
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
cR5N5R2+846I54)81[Kgt$XR5N$R5N5R2[+++846I54)8B04[^BII0QRWRG58C6B64[d++c1R34R+846I54)81[846I54KLLK05B81[+++++846I54)N09[W8R5N[+Qd++++++++++++++++++++++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6d++++++++++++cQR5N5R2dcR5N5R2+846I54)81[K1I$R5N5R2[+++846I54)8B04[^BII0Q8IRG58C6B64[d++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6dcQR5N5R2d
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+W8R5N$F$Ggt+)+3$XltJXm$gtltFJgt+ )+C09R50WK+k+ LL3846I5438R5NK$JMgt+)+30GgtND+3040+300IC+30G+30846I54$gt$JJMlt$ltJgt+ )+846I548R5NLLC09$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7-00+51LI6R31I490a846I54Q8R5NLLC097
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
LTC+I1KY1L0KW88C0WU
L9B05+0WW+gt$XR5N$R5N5R2+YR84W+846I54KLLKXR5N$R5N5R2+Z
++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
LTC+I1KY1L0KW88C0WU
L9B05+0WW+1I$R5N5R2+YR84W+846I54KLLK$R5N5R2+Z++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++++++gt2WR1K0I45B662-[WE85[7U++++KKK
Key Game Components
33
Lifecycle
Graphics Sound
Input
Assets
Activity LifecycleLifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Process LifecycleLifecycle
Android keeps application processes around for as long as possible
ndash Even when the activity is closed with V585W`-7 or the back key is pressed
The foreground activity process is considered the most important
ndash It can still be killed as a last resort
Visible activities are also given high priority
ndash Backgrounded activities are considered less important
ndash Processes with no active activities are killed first
Implications of the Process LifecycleLifecycle
Be careful with static initializers
ndash Your library cannot be unloaded while your process is active
bull Donrsquot assume that your static initializers will be run when your activity is created
Be careful with threads
ndash Threads are tied to the process not the activity
bull Your threads will continue to run at reduced priority even if your activity is backgrounded or destroyed
ndash Gameplay should stop during onPause
bull It might make sense to keep certain threads running - your activity may still be visible
ndash Make sure all native code is cleaned up during onDestroy
bull Users expect that your application will no longer be active when its activity is destroyed
The Basics
Key handling
ndash Your device most likely has capacitive buttons
bull Look for complete state transitions of I8m2I_8I8m2AL
bull Avoid overriding 45WLR`m2N8R
ndash Use I8m290R5L0I8m2I8Camp6WW
bull Keep your game behaving like an Android application
TouchMultitouch handling
ndash With I8I9`N8R
bull take advantage of built-in gesture processing
ndash use gt0GWR96RRI6 and GWR96RRI6
ndash Most devices now support multitouch
bull determine if your device can track distinct points
ndash `Wgt2WR1FR96-F$AltA(gtltXAJA(JgtJX)
37
Input
Other Input
Trackball handling
ndash With I86TB00N8R
bull Unhandled events turn into dpad events
Motion handling
ndash With I8gt8WI6`8C4
bull Must be registered with the gt8WI68C6
bull Disable unneeded sensors especially when paused
ndash Active sensors will quickly drain the battery
38
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
OpenGL
GLSurfaceView
ndash Creates the compatible context
bull Contexts are shared between native code and Dalvik
ndash Creates a rendering thread
ndash Releases the context during onPause
ndash Not the most efficient way to multitask withOpenGL but it avoids some driver issues
When context is lost
ndash Reload resources
bull Textures
bull Buffer objects
bull Shaders
ndash Names donrsquot persist
40
Graphics
Texture Formats
Android encourages innovation in hardware
ndash Chipset vendors use several kinds of proprietary texture compression formats
ndash OpenGL ES supports multiple compressed formats none mandatory
Solutions
ndash Uncompressed Textures
ndash Use ETC1 ndash broad support in 20
bull Optimized around photographic data
bull No Alpha
ndash Use Multi-APK (coming soon)
ndash Put textures on an asset server
bull Detect support at runtime
bull Download to each device
41
Graphics
Drawing for Performance
Draw order is important
ndash Has no impact on some platforms means everything on others
ndash Draw front to back to make best use of early rejects
Use VBOs
ndash Avoid unnecessary state changes
Textures
ndash Use power of 2 sized textures
bull It can be very slow
bull On some chipsets not all address modes work
42
Graphics
Writing Compatible Shaders
Query query
ndash Make sure to query for number of attributes varying and uniforms supported
bull Varies between devices
bull Not respecting will make your application crash
bull ldquoSupportedrdquo does not mean ldquoperforms wellrdquo
Conditions
ndash Avoid as much as possible
bull if necessary put them last in the shader
ndash Use mix() clamp() etc to create the same result
discard()
ndash Avoid discard()
bull if necessary it should be last
43
Graphics
Audio Solutions
Full track audio
s 45amp026
bull Plays multiple formats with codec support
bull Plays from filesystem or from network
bull Has high latency memory and CPU usage for quick sound effects
Sound effects and clips
s gtI984ampII0
bull Plays multiple formats with codec support
bull Preloads audio files to a pool
ndash Plays them with low latency
44
Sound
Audio Solutions
Application-generated audio
s $945I6T
bull Plays PCM audio only with minimal latency
bull Useful for applications that wish to perform sound processing or mixing
OpenSLES
ndash Combines capabilities of 45amp026 and $945I6T
ndash Available only in the NDK
ndash Requires Android 23 and higher
45
Sound
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
Use native AssetManager
ndash Gingerbread and Beyond
Targeting tricky trying tasks
Troubleshooting Tips and Tricks
47
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
One JNI Context Per Thread
Threading Options
49
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
JNI Context 2
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
OR
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
If all else fails Market filters
ndash Instruction set
ndash ARMv5ARMv7
ndash GL version
ndash Platform release
ndash Use Device Availability
Tips Standing Out from the Crowd
Start Small
ndash Download assets as-needed
ndash Hook me early instead of making me wait
Use Android backuprestore service (save to the cloud)
ndash Keep my progress when I switch devices
Support multiple control schemes
ndash Trackball D-pad virtual stick
ndash Let me decide what works best
Support install-to-SD
ndash Android Market users will knock your ratings if you donrsquot
51
Tips Standing Out from the Crowd
Profiling
ndash In-game profiling to select optimal settings per-device
Social
ndash Hook into social networks
ndash Use OpenID
Build a live wallpaper
ndash Own the userrsquos home screen with stats avatars
Analytics
ndash Market and in-game
In-app payments
ndash Consider alternative monetization techniques
52
Troubleshooting Development Tools
NVIDIA Debug Manager for Eclipse
ndash Simplifies setup for native debugger under Eclipse
bull developernvidiacomtegranvidia-debug-manager-android-ndk
WinGDB
ndash Use Visual Studio to debug Android NDK applications
bull wwwwingdbcom
vs-android
ndash Native MSBuild files for Android toolchain
bull vs-androidgooglecodecom
53
Troubleshooting Performance Tools
NVIDIA PerfHUD ES
ndash developernvidiacomtegraperfhud-es
Adreno Profiler
ndash developerqualcommcomshowcaseadreno-profiler
POWERVR Insider Utilities
ndash Including PVRTrace and PVRTune
ndash wwwimgteccompowervrinsiderpowervr-utilitiesasp
54
developerandroidcomsdkndkGoogleGameDevAndroid
Feedback httpgooglNudVs
QampA
55
Using NativeActivity Compatibly
26
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
Platform-specific Resources
Using NativeActivity Compatibly
27
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dV0WcQBII0d++++cBII0+81[8IRG58C6B64[dR69cQBII0dcQ6WI96Wd
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dR69cQBII0d++++cBII0+81[8IRG58C6B64[dV0WcQBII0dcQ6WI96Wd
Using NativeActivity Compatibly
28
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
cR5N5R2+846I54)81[Kgt$XR5N$R5N5R2[+++846I54)8B04[^BII0QRWRG58C6B64[d++c1R34R+846I54)81[846I54KLLK05B81[+++++846I54)N09[W8R5N[+Qd++++++++++++++++++++++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6d++++++++++++cQR5N5R2dcR5N5R2+846I54)81[K1I$R5N5R2[+++846I54)8B04[^BII0Q8IRG58C6B64[d++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6dcQR5N5R2d
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+W8R5N$F$Ggt+)+3$XltJXm$gtltFJgt+ )+C09R50WK+k+ LL3846I5438R5NK$JMgt+)+30GgtND+3040+300IC+30G+30846I54$gt$JJMlt$ltJgt+ )+846I548R5NLLC09$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7-00+51LI6R31I490a846I54Q8R5NLLC097
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
LTC+I1KY1L0KW88C0WU
L9B05+0WW+gt$XR5N$R5N5R2+YR84W+846I54KLLKXR5N$R5N5R2+Z
++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
LTC+I1KY1L0KW88C0WU
L9B05+0WW+1I$R5N5R2+YR84W+846I54KLLK$R5N5R2+Z++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++++++gt2WR1K0I45B662-[WE85[7U++++KKK
Key Game Components
33
Lifecycle
Graphics Sound
Input
Assets
Activity LifecycleLifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Process LifecycleLifecycle
Android keeps application processes around for as long as possible
ndash Even when the activity is closed with V585W`-7 or the back key is pressed
The foreground activity process is considered the most important
ndash It can still be killed as a last resort
Visible activities are also given high priority
ndash Backgrounded activities are considered less important
ndash Processes with no active activities are killed first
Implications of the Process LifecycleLifecycle
Be careful with static initializers
ndash Your library cannot be unloaded while your process is active
bull Donrsquot assume that your static initializers will be run when your activity is created
Be careful with threads
ndash Threads are tied to the process not the activity
bull Your threads will continue to run at reduced priority even if your activity is backgrounded or destroyed
ndash Gameplay should stop during onPause
bull It might make sense to keep certain threads running - your activity may still be visible
ndash Make sure all native code is cleaned up during onDestroy
bull Users expect that your application will no longer be active when its activity is destroyed
The Basics
Key handling
ndash Your device most likely has capacitive buttons
bull Look for complete state transitions of I8m2I_8I8m2AL
bull Avoid overriding 45WLR`m2N8R
ndash Use I8m290R5L0I8m2I8Camp6WW
bull Keep your game behaving like an Android application
TouchMultitouch handling
ndash With I8I9`N8R
bull take advantage of built-in gesture processing
ndash use gt0GWR96RRI6 and GWR96RRI6
ndash Most devices now support multitouch
bull determine if your device can track distinct points
ndash `Wgt2WR1FR96-F$AltA(gtltXAJA(JgtJX)
37
Input
Other Input
Trackball handling
ndash With I86TB00N8R
bull Unhandled events turn into dpad events
Motion handling
ndash With I8gt8WI6`8C4
bull Must be registered with the gt8WI68C6
bull Disable unneeded sensors especially when paused
ndash Active sensors will quickly drain the battery
38
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
OpenGL
GLSurfaceView
ndash Creates the compatible context
bull Contexts are shared between native code and Dalvik
ndash Creates a rendering thread
ndash Releases the context during onPause
ndash Not the most efficient way to multitask withOpenGL but it avoids some driver issues
When context is lost
ndash Reload resources
bull Textures
bull Buffer objects
bull Shaders
ndash Names donrsquot persist
40
Graphics
Texture Formats
Android encourages innovation in hardware
ndash Chipset vendors use several kinds of proprietary texture compression formats
ndash OpenGL ES supports multiple compressed formats none mandatory
Solutions
ndash Uncompressed Textures
ndash Use ETC1 ndash broad support in 20
bull Optimized around photographic data
bull No Alpha
ndash Use Multi-APK (coming soon)
ndash Put textures on an asset server
bull Detect support at runtime
bull Download to each device
41
Graphics
Drawing for Performance
Draw order is important
ndash Has no impact on some platforms means everything on others
ndash Draw front to back to make best use of early rejects
Use VBOs
ndash Avoid unnecessary state changes
Textures
ndash Use power of 2 sized textures
bull It can be very slow
bull On some chipsets not all address modes work
42
Graphics
Writing Compatible Shaders
Query query
ndash Make sure to query for number of attributes varying and uniforms supported
bull Varies between devices
bull Not respecting will make your application crash
bull ldquoSupportedrdquo does not mean ldquoperforms wellrdquo
Conditions
ndash Avoid as much as possible
bull if necessary put them last in the shader
ndash Use mix() clamp() etc to create the same result
discard()
ndash Avoid discard()
bull if necessary it should be last
43
Graphics
Audio Solutions
Full track audio
s 45amp026
bull Plays multiple formats with codec support
bull Plays from filesystem or from network
bull Has high latency memory and CPU usage for quick sound effects
Sound effects and clips
s gtI984ampII0
bull Plays multiple formats with codec support
bull Preloads audio files to a pool
ndash Plays them with low latency
44
Sound
Audio Solutions
Application-generated audio
s $945I6T
bull Plays PCM audio only with minimal latency
bull Useful for applications that wish to perform sound processing or mixing
OpenSLES
ndash Combines capabilities of 45amp026 and $945I6T
ndash Available only in the NDK
ndash Requires Android 23 and higher
45
Sound
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
Use native AssetManager
ndash Gingerbread and Beyond
Targeting tricky trying tasks
Troubleshooting Tips and Tricks
47
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
One JNI Context Per Thread
Threading Options
49
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
JNI Context 2
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
OR
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
If all else fails Market filters
ndash Instruction set
ndash ARMv5ARMv7
ndash GL version
ndash Platform release
ndash Use Device Availability
Tips Standing Out from the Crowd
Start Small
ndash Download assets as-needed
ndash Hook me early instead of making me wait
Use Android backuprestore service (save to the cloud)
ndash Keep my progress when I switch devices
Support multiple control schemes
ndash Trackball D-pad virtual stick
ndash Let me decide what works best
Support install-to-SD
ndash Android Market users will knock your ratings if you donrsquot
51
Tips Standing Out from the Crowd
Profiling
ndash In-game profiling to select optimal settings per-device
Social
ndash Hook into social networks
ndash Use OpenID
Build a live wallpaper
ndash Own the userrsquos home screen with stats avatars
Analytics
ndash Market and in-game
In-app payments
ndash Consider alternative monetization techniques
52
Troubleshooting Development Tools
NVIDIA Debug Manager for Eclipse
ndash Simplifies setup for native debugger under Eclipse
bull developernvidiacomtegranvidia-debug-manager-android-ndk
WinGDB
ndash Use Visual Studio to debug Android NDK applications
bull wwwwingdbcom
vs-android
ndash Native MSBuild files for Android toolchain
bull vs-androidgooglecodecom
53
Troubleshooting Performance Tools
NVIDIA PerfHUD ES
ndash developernvidiacomtegraperfhud-es
Adreno Profiler
ndash developerqualcommcomshowcaseadreno-profiler
POWERVR Insider Utilities
ndash Including PVRTrace and PVRTune
ndash wwwimgteccompowervrinsiderpowervr-utilitiesasp
54
developerandroidcomsdkndkGoogleGameDevAndroid
Feedback httpgooglNudVs
QampA
55
Using NativeActivity Compatibly
27
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dV0WcQBII0d++++cBII0+81[8IRG58C6B64[dR69cQBII0dcQ6WI96Wd
coY10+N6W5I8[pKl[+8I458C[9RV3q[odc6WI96Wd++++cBII0+81[RWRG58C6B64[dR69cQBII0d++++cBII0+81[8IRG58C6B64[dV0WcQBII0dcQ6WI96Wd
Using NativeActivity Compatibly
28
Platform-specific resources
ndash can be used to define boolean values
bull activities can be enabled based upon these values
cR5N5R2+846I54)81[Kgt$XR5N$R5N5R2[+++846I54)8B04[^BII0QRWRG58C6B64[d++c1R34R+846I54)81[846I54KLLK05B81[+++++846I54)N09[W8R5N[+Qd++++++++++++++++++++++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6d++++++++++++cQR5N5R2dcR5N5R2+846I54)81[K1I$R5N5R2[+++846I54)8B04[^BII0Q8IRG58C6B64[d++c58R8R3V50R6d++++cR5I8+846I54)81[846I54K58R8RKR5I8K$JX[Qd++++cRCI62+846I54)81[846I54K58R8RKRCI62K$AX(lt[Qd++cQ58R8R3V50R6dcQR5N5R2d
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
29
Dynamic libraries
ndash create stub libraries as interfaces to your game engine
PXJltFlt+ )+-00+123456758094+-PXJltFlt7Q05BW88C0WQ$846I54K1T58094+-PXJltFlt7Q05BW8R5NQ$846I54K1T58094+-PXJltFlt7Q05BWE85Q$846I54K1T
$ampampamp$Flt+)+846I543r$ampampAgt+)+05BW88C0W+05BW8R5N+05BWE85$ampampampJ+)+60W$ampamp$MJ+)+61B5+61B53NS
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
Using NativeActivity Compatibly
30
Dynamic Libraries
ndash create multiple libraries as interfaces to your game engine
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+WE85$F$Ggt+)+3$XltJXm$gtltFJgt+ )+LL3846I54K$JMgt+)+30GgtND+3040+300IC$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7
$amp$(+ )+-00+123456758094+-$lt=$ltgt7$A+)+W8R5N$F$Ggt+)+3$XltJXm$gtltFJgt+ )+C09R50WK+k+ LL3846I5438R5NK$JMgt+)+30GgtND+3040+300IC+30G+30846I54$gt$JJMlt$ltJgt+ )+846I548R5NLLC09$gt($ltJMlt$ltJgt+ )+W88C0W58094+-MAJgt($ltJMlt$ltO7-00+51LI6R31I490a846I54Q8R5NLLC097
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
Using NativeActivity Compatibly
31
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
LTC+I1KY1L0KW88C0WU
L9B05+0WW+gt$XR5N$R5N5R2+YR84W+846I54KLLKXR5N$R5N5R2+Z
++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
Using NativeActivity Compatibly
32
Dynamic libraries
ndash the third library must be loaded manually before the native activity library
ndash we can extend NativeActivity to do this
ndash with our JNI-based class we load in order
LTC+I1KY1L0KW88C0WU
L9B05+0WW+1I$R5N5R2+YR84W+846I54KLLK$R5N5R2+Z++++WRR5+Z++++++++gt2WR1K0I45B662-[W88C0W[7U++++++++gt2WR1K0I45B662-[WE85[7U++++KKK
Key Game Components
33
Lifecycle
Graphics Sound
Input
Assets
Activity LifecycleLifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Activity Lifecycle
Activity Starts
onCreate()
onStart()
onResume()
Activity is Running
onPause()
onStop()
onDestroy()
Activity is Shut Down
Another activity comes in front of the activity
The activity is no longer visible
Other applications need memory
Process is Killed
User navigates back to the activity
The activity comes to the foreground
The activity comes to the foreground
onRestart()
Lifecycle
Process LifecycleLifecycle
Android keeps application processes around for as long as possible
ndash Even when the activity is closed with V585W`-7 or the back key is pressed
The foreground activity process is considered the most important
ndash It can still be killed as a last resort
Visible activities are also given high priority
ndash Backgrounded activities are considered less important
ndash Processes with no active activities are killed first
Implications of the Process LifecycleLifecycle
Be careful with static initializers
ndash Your library cannot be unloaded while your process is active
bull Donrsquot assume that your static initializers will be run when your activity is created
Be careful with threads
ndash Threads are tied to the process not the activity
bull Your threads will continue to run at reduced priority even if your activity is backgrounded or destroyed
ndash Gameplay should stop during onPause
bull It might make sense to keep certain threads running - your activity may still be visible
ndash Make sure all native code is cleaned up during onDestroy
bull Users expect that your application will no longer be active when its activity is destroyed
The Basics
Key handling
ndash Your device most likely has capacitive buttons
bull Look for complete state transitions of I8m2I_8I8m2AL
bull Avoid overriding 45WLR`m2N8R
ndash Use I8m290R5L0I8m2I8Camp6WW
bull Keep your game behaving like an Android application
TouchMultitouch handling
ndash With I8I9`N8R
bull take advantage of built-in gesture processing
ndash use gt0GWR96RRI6 and GWR96RRI6
ndash Most devices now support multitouch
bull determine if your device can track distinct points
ndash `Wgt2WR1FR96-F$AltA(gtltXAJA(JgtJX)
37
Input
Other Input
Trackball handling
ndash With I86TB00N8R
bull Unhandled events turn into dpad events
Motion handling
ndash With I8gt8WI6`8C4
bull Must be registered with the gt8WI68C6
bull Disable unneeded sensors especially when paused
ndash Active sensors will quickly drain the battery
38
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
Androidify Your Game
39
Donrsquot break the ldquohard buttonsrdquo
ndash Back dismiss dialogs exit menus pause the game
ndash Menu pause launch options dialog
ndash Home pause (not quit)
Donrsquot break the volume buttons
ndash Donrsquot eat volume button messages
s WR=I091I8R6I0gtR61-$945I8C6Kgtlt$AgtJ7
Donrsquot let the ldquohard buttonsrdquo break your game
ndash Very easy to press accidentally on some devices
bull Pause and give user the option to exit when back is pressed
bull Save game state whenever possible onPauseonStop
Input
OpenGL
GLSurfaceView
ndash Creates the compatible context
bull Contexts are shared between native code and Dalvik
ndash Creates a rendering thread
ndash Releases the context during onPause
ndash Not the most efficient way to multitask withOpenGL but it avoids some driver issues
When context is lost
ndash Reload resources
bull Textures
bull Buffer objects
bull Shaders
ndash Names donrsquot persist
40
Graphics
Texture Formats
Android encourages innovation in hardware
ndash Chipset vendors use several kinds of proprietary texture compression formats
ndash OpenGL ES supports multiple compressed formats none mandatory
Solutions
ndash Uncompressed Textures
ndash Use ETC1 ndash broad support in 20
bull Optimized around photographic data
bull No Alpha
ndash Use Multi-APK (coming soon)
ndash Put textures on an asset server
bull Detect support at runtime
bull Download to each device
41
Graphics
Drawing for Performance
Draw order is important
ndash Has no impact on some platforms means everything on others
ndash Draw front to back to make best use of early rejects
Use VBOs
ndash Avoid unnecessary state changes
Textures
ndash Use power of 2 sized textures
bull It can be very slow
bull On some chipsets not all address modes work
42
Graphics
Writing Compatible Shaders
Query query
ndash Make sure to query for number of attributes varying and uniforms supported
bull Varies between devices
bull Not respecting will make your application crash
bull ldquoSupportedrdquo does not mean ldquoperforms wellrdquo
Conditions
ndash Avoid as much as possible
bull if necessary put them last in the shader
ndash Use mix() clamp() etc to create the same result
discard()
ndash Avoid discard()
bull if necessary it should be last
43
Graphics
Audio Solutions
Full track audio
s 45amp026
bull Plays multiple formats with codec support
bull Plays from filesystem or from network
bull Has high latency memory and CPU usage for quick sound effects
Sound effects and clips
s gtI984ampII0
bull Plays multiple formats with codec support
bull Preloads audio files to a pool
ndash Plays them with low latency
44
Sound
Audio Solutions
Application-generated audio
s $945I6T
bull Plays PCM audio only with minimal latency
bull Useful for applications that wish to perform sound processing or mixing
OpenSLES
ndash Combines capabilities of 45amp026 and $945I6T
ndash Available only in the NDK
ndash Requires Android 23 and higher
45
Sound
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
The JNI Solution
Get the APK file name
s I8RYRKCR$LL05R5I8J8VI-7KWI9656
Use the asset manager code to get an AssetFileDescriptor
s V4++I8RYRKCR$WWRW-7KIL8F4-[IIR`26I54KL8C[7U
Read the offset and length from the AssetFileDescriptor
s 0I8C+IVVWR++V4KCRgtR6RVVWR-7U0I8C+08CR`++V4KCR0648CR`-7UV4K0IW-7U
Open the APK file at the specified offset and read the specified length
46
Assets
Use a native Zip Utility
ndash Slightly less future-proof
ndash Potentially faster
bull Make sure to cache the Zip directory
bull Get the offset and length if the item isnrsquot compressed
Use native AssetManager
ndash Gingerbread and Beyond
Targeting tricky trying tasks
Troubleshooting Tips and Tricks
47
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
Troubleshooting Threading Dalvik and the NDK
Problem App crashes mysteriously
Solution Check your threading
ndash JNI contexts are per-thread
48
Activity
JNI Context
Main UI Loop Game Loop
Framework Class
One JNI Context Per Thread
Threading Options
49
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
JNI Context 2
Activity
JNI Context 1
Main UI loop
Game loop
Framework Class
OR
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
Troubleshooting Performance
Check for older hardware
ndash ARM7 CPUs (use cpu-features lib)
ndash No support for OpenGL 2
Fallbacks for older HW
ndash Use 16-bit texturest M5R1LFRI62KLR5I8WK58amp6V664I8V5C++M5R1LKI8V5CK$ltGMuuuu
ndash Use smaller render target scale up
bull Framework will do it for you with gt96V(I046KWRF5Y4gt5h-7
bull Pixels are expensive especially on tablets
50
If all else fails Market filters
ndash Instruction set
ndash ARMv5ARMv7
ndash GL version
ndash Platform release
ndash Use Device Availability
Tips Standing Out from the Crowd
Start Small
ndash Download assets as-needed
ndash Hook me early instead of making me wait
Use Android backuprestore service (save to the cloud)
ndash Keep my progress when I switch devices
Support multiple control schemes
ndash Trackball D-pad virtual stick
ndash Let me decide what works best
Support install-to-SD
ndash Android Market users will knock your ratings if you donrsquot
51
Tips Standing Out from the Crowd
Profiling
ndash In-game profiling to select optimal settings per-device
Social
ndash Hook into social networks
ndash Use OpenID
Build a live wallpaper
ndash Own the userrsquos home screen with stats avatars
Analytics
ndash Market and in-game
In-app payments
ndash Consider alternative monetization techniques
52
Troubleshooting Development Tools
NVIDIA Debug Manager for Eclipse
ndash Simplifies setup for native debugger under Eclipse
bull developernvidiacomtegranvidia-debug-manager-android-ndk
WinGDB
ndash Use Visual Studio to debug Android NDK applications
bull wwwwingdbcom
vs-android
ndash Native MSBuild files for Android toolchain
bull vs-androidgooglecodecom
53
Troubleshooting Performance Tools
NVIDIA PerfHUD ES
ndash developernvidiacomtegraperfhud-es
Adreno Profiler
ndash developerqualcommcomshowcaseadreno-profiler
POWERVR Insider Utilities
ndash Including PVRTrace and PVRTune
ndash wwwimgteccompowervrinsiderpowervr-utilitiesasp
54
developerandroidcomsdkndkGoogleGameDevAndroid
Feedback httpgooglNudVs
QampA
55