2. Outline
o NAVIGON Mobile Navigator
o Hybrid Android Application (Native & Java)
o Development Tools & Helpers
o Challenges
o Performance for low end devices
o Developing aids for such complex project
o Flexibility & scalability
o Android platform segmentation
6. Mobile Navigator Starting Point
• Initially designed for
automotive
• Simple interfaces for
fast development
• Reduce client side
development effort
• Knowledge
sharing/reusing
between platforms
• Brought automotive
quality to mobile
Content Data
Core Library
Core API
Custom HMI
OS
7. Reality View
Tunnels &
Bridges
Performance gain by using native approach
• Complex algorithms
• Complex routing
support
• Hardware accelerated
drawing
• TTS House
number info
Sound data
POI
• Huge content size
• Data compression and
optimization
• Efficiently pre-compiled
data format
Country info
3D Data
Terrain
elevation
Street
lines
9. Core release distribution
• Cmake
• Compiler independent
• Same build scripts
• Just different compiler paths
• Jenkins as build server
• Excellent platform independent build server system
• Support for OS independent nodes:
• Linux
• Windows
10. Native Core Integration
• JNI mapping
• Existing native API
• Core API hooks
• C++ classes to Objects
• Allows us to implement RPC protocol
Core Components (C++)
Router Name
Browser
Advisor Map
Drawer
Traffic
TMC …
JNI
11. RPC over Core API
• Remote calls to Core code via a custom RPC
over TCP/IP.
• Light binary protocol
• Application is in control
• Act as separation layer between C++ core and
Android native Java implementation
• Can record for issue replays
• Replay using desktop dev-tool
12. Java HMI – single process architecture
Java Proxy
Implementation
Core Server
Core Library
Core Server
Stream IO
JNI
API (Java)
Java HMI
API
Java Proxy
translates HMI
function calls into a
data stream which
is passed to a
single JNI function.
Core Server Library
decodes HMI function
calls.
Similar architecture also valid
with C# and COM on other
platforms
• C++ remote implementation of interfaces
that acts as a proxy to the actual
implementation
13. Core Library multi process architecture
Core Proxy Library
Server Application
Core Library &
actual
implementation
Core Server
Stream IO
Core Proxy
Stream IO
TCP/IP
HMI
API
API
API
Core Proxy interacts between HMI and
Core to separate the HMI process from
main process.
Proxy encodes
HMI function calls.
Core Server decodes
HMI function calls.
14. Java HMI – multi process architecture
Java Proxy
(Package)
Native Core Library
Core Library
Core Server
Stream IO
JNI
Java HMI
Java Server
Application
TCP/IP
Actual API
implementation
API (Java)
Java Proxy
translates HMI
function calls into a
data stream which
is passed to
JavaServer
Application via
TCP/IP.
Java Server
Application passes the
data stream to JNI.
Similar architecture also valid with C#
and COM on other platforms
15. Logging mode
Log Player
Application
Core Native
Library
Core Server
Stream IO
Log Player
Core API
File IO
Playback of HMI calls
binary log-file.
Application with
Core logging
enabled
Core Native
Library
Core Server
Stream IO
Core proxy
Core API
File IO
Recording of HMI calls
to binary log-file
considering relative
time-stamps.
HMI
API
17. Open Gl ES
• Replaced software rendering
• Better user experience
• Advantages:
• Increase drawing performance
• Already tested on other platforms
• Immersion into the city landscape
• Disadvantages:
• Opengl ES 2 for better texture filtering
• Small issues encountered on the way
18. Open GL integration challenges
• GlEs1.0 have limitations
• GlEs2.0 is available only from 2.2
• NativeActivity only from 2.3
• Native drawing thread
• Sync needed between Java side and native side
• Device specific issues
• Some have Open GL emulation
• Some have bad support
20. Android Challenges
• Supporting the full range of screen sizes
• Same code base, same APK
• ldpi, mdpi, hdpi, xhdpi, xxhdpi
• small, normal, large, extra large
21. Android Challenges
• Supporting the full range of screen sizes
• Same code base, same APK
• ldpi, mdpi, hdpi, xhdpi, xxhdpi
• small, normal, large, extra large
22. Android Challenges
• Supporting the full range of screen sizes
• Same code base, same APK
• ldpi, mdpi, hdpi, xhdpi, xxhdpi
• small, normal, large, extra large
23. Android Challenges
• Supporting the full range of screen sizes
• Same code base, same APK
• ldpi, mdpi, hdpi, xhdpi, xxhdpi
• small, normal, large, extra large
24. Android Challenges
• Supporting the full range of screen sizes
• Same code base, same APK
• ldpi, mdpi, hdpi, xhdpi, xxhdpi
• small, normal, large, extra large
25. Android Challenges
• Supporting the full range of screen sizes
• Same code base, same APK
• ldpi, mdpi, hdpi, xhdpi, xxhdpi
• small, normal, large, extra large
26. Android Challenges
• Reduce APK size
• Requested by device manufacturers and operators
• Solutions:
• Download image resource set from content server
• Using LruCache for faster image loading
• (introduced in API 12, but added to Android Support library)
27. // Get max available VM memory
final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
Sample code taken from http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html
28. // Get max available VM memory
final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
// Use 1/5th of the available memory for this memory cache.
final int cacheSize = maxMemory / 5;
Sample code taken from http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html
29. // Get max available VM memory
final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
// Use 1/5th of the available memory for this memory cache.
final int cacheSize = maxMemory / 5;
LruCache<String, Bitmap> mMemoryCache =
new LruCache<String,Bitmap>(cacheSize);
Sample code taken from http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html
30. // Get max available VM memory
final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
// Use 1/5th of the available memory for this memory cache.
final int cacheSize = maxMemory / 5;
LruCache<String, Bitmap> mMemoryCache =
new LruCache<String, Bitmap>(cacheSize) {
@Override
protected int sizeOf(String key, Bitmap bitmap) {
// The cache size will be measured in kilobytes rather than
// number of items.
return bitmap.getByteCount() / 1024;
}
};
Sample code taken from http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html