Presentation from David Wingrove & Katie Merrill from Golden Hammer Software http://www.goldenhammersoftware.com/
From the Barcelona Android User Group meetup: http://www.meetup.com/Barcelona-Android-User-Group/events/166734982/
4. Overview
NDK recap
What goes where? C++ vs Java
Streamlining packaged app data
Eliminating Data Duplication
Compiling multiple architectures
Other quirks we’ve run into
Some downloads info about our apps
7. NDK
Android.mk
(shared lib – loaded by java)
LOCAL_MODULE := libGHEngine
LOCAL_SRC_FILES :=
../../GHEngine/obj/local/armeabi/libGHEngine.a
include $(PREBUILT_STATIC_LIBRARY)
LOCAL_STATIC_LIBRARIES += libGHEngine
include $(BUILD_SHARED_LIBRARY)
$(shell cp libs/armeabi/libGHBowling.so
../../../GHBowlingBase/libs/armeabi)
8. NDK
JNI
Loading the C++ Library
public class GHBowlingBaseActivity
extends Activity {
static {
System.loadLibrary("GHBowling");
}
}
Loads the file named libGHBowling.so
9. NDK
JNI
Java (calling C++)
public class GHEngineInterface {
public native void runNativeFrame();
public native void launchNativeApp(int windowWidth,
int windowHeight,
String externalStoragePath,
int isTablet,int iapIsOn);
//resizeWindow, handleTouchStart, handleTouchEnd, handleTouchPos
//handleAcceleration, handleJavaPause, handleJavaResume,
//handleJavaShutdown,handleBackPressed, calculatePublicKey,
//onInterstitialRewardGranted,onRewardInterstitialAvailabilityChange,
//onInterstitialDismiss, loadFile,handleTextureLoadConfirmed,
//onAdActivation, onAdDeactivation, onIAPPurchase
}
13. What goes Where?
C++ or Java
C++
Java
All your platform-independent/pre-existing code
Bare minimum wrapper for Android implementation of
platform services
Typical Android platform code
Middleware integration
Can swap middleware vendors of the same service
without touching C++
Exceptions:
OpenGL (initialization in Java, most code in C++ or GLSL)
File I/O (mix of Java, C++)
14. What Goes Where
Java
OpenGL initialization
Sound through SoundPool
File handle loading through AssetManager
Image loading through BitmapFactory
Google Play, In-App Billing, etc
Ads and other middleware integration
AdMob, AdColony, Chartboost, PlayHaven, Facebook, etc
Input Handling
(touches, accelerometer, buttons/gamepad)
15. What Goes Where
C++
All your game code
OpenGL rendering code
Ideally 90% of your app
Need to handle reinit after lost device
fopen using file handle from Java
Thin wrapper over JNI calls for
everything else
16. What Goes Where
Our code distribution.
2800 lines Java
1600 in base project
1200 in master project
Includes middleware integration
50k-150k lines C++
Varies depending on game
6400 Android-specific C++
17. Eliminating Data Duplication
Problem
Eclipse wants all data underneath
project
We want to reuse data (between
projects) in our own directory structure
We hate maintaining multiple copies of
the same data files.
18. Eliminating Data Duplication
Solution
Batch file/shell script to copy data
On Mac
cp ../../../../../data/GHBowling/ballrollloop.wav
../../../GHBowling/assets/ballrollloop.wav
cp
../../../../../data/Bowling/GHBowlingAndroid/backwall.jpg ../.
./../GHBowling/assets/backwall.jpg
On Windows
copy ..........dataGHBowlingballrollloop.wav
......GHBowlingassetsballrollloop.wav
copy
..........dataBowlingGHBowlingAndroidbackwall.jpg ...
...GHBowlingassetsbackwall.jpg
19. Eliminating Data Duplication
Batch File Generation
Tool for initial generation
Looks through set of directories with a specified
order of preference
Some files are different per-platform
We may have Android-specific files
We may not, but we prefer iOS-specific to generic
Downside: some unnecessary files get copied
Maintenance usually done by hand
20. Packaged App Data
Problem
Data is packaged through Android build
process
All files except those with certain
excluded file extensions (precompressed file types) are
automatically compressed.
Platform-agnostic file reading code
doesn’t know to uncompress: sees
garbage
22. App Data Compression
Solution
One option: forgo Eclipse and pass –0
to the AAPT via command line
(universally or for certain extensions)
What we do
cp
../../../../../data/GHBowlingiOS/arrowpixel.glsl ../
../../GHBowling/assets/arrowpixel.glsl.mp3
23. Compiling for x86
(or other architectures)
In Application.mk:
APP_ABI := x86 armeabi
Supported values:
armeabi
armeabi-v7a
x86
mips
all
24. Compiling for x86
Problem
Shared library Android.mk needs to
include the correct static library for each
architecture
For arm: /armeabi/libGHEngine.a
For x86: /x86/libGHEngine.a
25. Compiling for x86
Solution
include $(CLEAR_VARS)
LOCAL_MODULE := libGHEngine
LOCAL_SRC_FILES :=
../../GHEngine/obj/local/$(TARGET_ARCH_ABI)/libGHEngine.a
include $(PREBUILT_STATIC_LIBRARY)
26. Building on Windows
Problem
We really like verbose filenames
GHBowlingYellowBallThrowWith190Degre
eSpinTransitionXMLLoaderTransition.cpp
Our GHEngine project has lots of files
Linker includes all of those filenames in
one shell command
Exceeds maximum line length on
Windows cmd (8191 characters)
27. Building on Windows
Problem
We really like verbose filenames
Ok, more like
GHGUIPopTransitionXMLLoader.cpp
Our GHEngine project has lots of files
Linker includes all of those filenames in
one shell command
Exceeds maximum line length on
Windows cmd (8191 characters)
28. Building on Windows
Solution
In Android.mk:
LOCAL_SHORT_COMMANDS := true
Build system generates intermediate list
file and then invokes it with a much
shorter command line
Downside: slower compiles
Can use only in projects that need it.