Best practices
In the following sections, we will guide you through the most common usage scenarios and reveal tips and easy-to-understand guidelines to help you get the most out of the HERE SDK for Android.
Optimization strategies
Explore further options to enhance the performance of the HERE SDK:
- Optimize map caching: Adjust the caching mechanisms by following the guidelines in our map caching documentation.
- Conditional HERE SDK initialization: To conserve resources, initialize the HERE SDK only when it is necessary.
- Adjust the frame fate: Modify the frame rate settings of the
MapViewto balance performance and visual fluidity. Detailed guidance can be found in the frame rate adjustment section below. - Simplify visuals with custom map styles: Employ custom map styles that include fewer elements to render, thereby enhancing rendering efficiency and reducing computational load.
When using the HERE SDK for Android Navigate, you can:
- Preload map data: Use offline maps to download and store map data in advance, allowing for smoother access and reduced reliance on live data connections.
Additionally, the HERE SDK provides versatile configuration options across various engines. For instance, with the SearchEngine, you can define SearchOptions to refine and limit the scope of returned search results.
Handling low memory states
When your application runs on a memory-constrained device or under heavy load, it is important to manage memory efficiently to avoid crashes. The HERE SDK provides mechanisms to optimize its memory usage under such scenarios.
Detect and respond to low memory warnings
To respond to memory pressure from the operating system (e.g., through onLowMemory() or onTrimMemory() callbacks), implement a handler that listens to memory warnings and takes action accordingly. Below is a possible implementation:
@Override
public void onTrimMemory(int level) {
super.onTrimMemory(level);
if (level >= ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL) {
handleLowMemory();
}
}
@Override
public void onLowMemory() {
super.onLowMemory();
handleLowMemory();
}A possible implementation for handleLowMemory() is shown below.
Enable low memory mode and purge the cache
To proactively reduce memory consumption, enable lowMemoryMode in SDKOptions and optionally purge the cache:
public void handleLowMemory() {
Log.d("Low Memory", "System is running low on memory. Initiating memory cleanup.");
SDKNativeEngine.getSharedInstance().purgeMemoryCaches(SDKNativeEngine.PurgeMemoryStrategy.FULL);
AuthenticationMode authenticationMode = AuthenticationMode.withKeySecret("YOUR_ACCESS_KEY_ID", "YOUR_ACCESS_KEY_SECRET");
SDKOptions options = new SDKOptions(authenticationMode);
options.lowMemoryMode = true;
try {
SDKNativeEngine.makeSharedInstance(context, options);
Log.d("Low Memory", "Reinitialized HERE SDK with low memory mode enabled.");
} catch (InstantiationErrorException e) {
Log.e("Low Memory", "Failed to reinitialize HERE SDK: " + e.error.name());
}
}Setting lowMemoryMode = true configures the SDK’s internal caches to use less memory. This can be beneficial on devices with limited RAM or during times of high memory pressure.
Turning on the lowMemoryMode will impact the performance of several HERE SDK features such as rendering the map view. Therefore, it may make sense to enable it only after you receive a low-memory warning from the operation system. The next section describes how to do this.
When the system sends memory pressure signals, use the following method to clear the HERE SDK’s internal caches:
SDKNativeEngine.getSharedInstance().purgeMemoryCaches(SDKNativeEngine.PurgeMemoryStrategy.FULL);This will release memory held by all in-memory caches and will help prevent OOM (Out of Memory) crashes.
Currently, only PurgeMemoryStrategy.FULL is supported, which clears all cached content without preserving any data.
Integrate JavaDoc into your IDE
In your release package you can find the latest API Reference as a zipped HTML package for offline use and a heresdk-javadoc.jar file containing the same data as a JAR package. When working in your IDE, then usually, the API Reference cannot be accessed right-away.
In order to get easy access to the API Reference from within your IDE of choice, you can integrate the API Reference file according to the instructions of your IDE.
As an example, for Android Studio, you can link the HERE SDK AAR to the JavaDoc file like so:
- For convenience, copy the
heresdk-javadoc.jarfile to the same folder as the HERE SDK AAR. - Open Android Studio and switch to the Project view: it is selectable from the pull-down menu above the navigation bar.
- Expand the External Libraries node. The HERE SDK AAR should appear.
- Right-click on the HERE SDK AAR file and choose Library Properties.

Screenshot showing step 4: Right-click on the HERE SDK AAR file.
- From the Library Properties dialog select the + sign.
- Navigate to the downloaded JavaDoc JAR file and select it.
- Choose JavaDocs as category for the selected
heresdk-javadoc.jarfile.

Screenshot showing step 7: Choose category for selected file.
- Click OK.
Finally, verify that the JavaDoc API Reference is available within your project.
Free resources
All HERE SDK classes will be garbage collected by Android if the instance is no longer referenced or set to null.
When the app's lifetime has ended, you can free resources by calling SDKNativeEngine.getSharedInstance().dispose(). Also, all references to SDKNativeEngine must be set to null (if any). Calling dispose() will stop pending requests and close open files and databases that are still running. After calling dispose() any related HERE SDK feature should no longer be used - unless you initialize the HERE SDK again: if you have created engines like SearchEngine() or RoutingEngine() using the default constructor, then these instances need to be recreated as well. Basically, all engines that used the same instance of the SDKNativeEngine need to be recreated after it was disposed.
Remove unused voice and font files to reduce the package size
By removing unused voice files like voice_package_ar-SA you can reduce the package size of the HERE SDK. These voice packages are only needed when you want to use turn-by-turn navigation with text-to-speech engines. Note that voice files are only included as part of Navigate.
On top, the HERE SDK contains several font files to render map labels for all supported languages. If you want to optimize the size of the overall app, you can remove selected fonts.
For example, the DroidSansFallback font uses the Simplified Chinese ideographs for shared Unicode code points. It is packaged in the HERE SDK AAR file (which can be opened by appending ".zip" to the file name):
assets/geoviz/fonts/DroidSansFallback.ttf
As another example, if you do not need to render the full set of Japanese characters, you can remove:
assets/geoviz/fonts/NotoSansJP-Regular.otf
Note that such fonts may not only be used in Japan and China, but also for other areas around the world when users switch their device language to Japanese or Chinese.
In order to remove files, you need to edit the app's build.gradle file.
For Android Gradle plugin versions >= 7.0 use AndroidResources like shown below:
android {
...
androidResources {
def languagesToRemove = ['ru-Ru', 'zh-HK']
def languagePatterns = languagesToRemove.collect {"!voice_package_${it}*"}.join(":")
ignoreAssetsPattern "${languagePatterns}:!DroidSansFallback.ttf:!NotoSansJP-Regular.otf"
}
...
}This excludes the listed fonts and voice assets from the final package. If you need to exclude more assets you need to list them as well.
Note that this example uses the delimiter syntax to exclude files.
Here you can find a list of all supported voice languages together with the name of the related voice skin that is stored inside the HERE SDK framework. Alternatively, look into the AAR by unzipping it and search for the voice and/or font files that you want to exclude.
If your Android Gradle plugin version is below 7.0 you can replace androidResources with aaptOptions.
NoteWhen you remove a font, it is recommended to switch the map language to any other language than the removed font. At least one font needs to be left to see any map labels. Note that each time a label needs to be displayed in a language for a font that was removed an error message is logged - for each character that is missing.
Note that the size of a font file may range from a few hundred kilobytes to a few megabytes in size. After removing selected fonts your application consumes less space when it is installed on a device. The maximum amount that you can save with these steps is approximately 11 MB.
Remove unused truck restriction icons to reduce the package size
You can manually remove unused truck restriction icons from the following paths inside the HERE SDK binary:
- /assets/geoviz/assets/oslo/truck_restriction/night/ui/
- /assets/geoviz/assets/oslo/truck_restriction/day/ui/
These icons are only used when creating vehicle restriction icons with IconProvider.createVehicleRestrictionIcon() and the IconProviderAssetType.UI setting. They are better suited for UI rendering compared to their IconProviderAssetType.MAP counterparts. If these files are removed, the HERE SDK will automatically fall back to using the MAP assets.
These SVG icons are included in the HERE SDK binary and occupy approximately 264 KB when compressed.
If you do not plan to use the IconProvider and if you do not need to show the MapFeatures.VEHICLE_RESTRICTION layer, then you can save considerably more space by removing the entire folder assets/geoviz/assets/oslo/truck_restriction.
To remove these files, follow the steps outlined in the section above.
Use ABI splits for Android to remove unused ABIs
Size management: with ABI splits you can reduce the package size of the HERE SDK AAR binary file. As a result, your application will occupy less storage space on a device.
By default, the HERE SDK for Android includes the following ABIs: armeabi-v7a, arm64-v8a (mainly used for devices) and x86, x86_64 (mainly used for emulators). You can enable ABI splits to build your app, for example, only for the armeabi-v7a or arm64-v8a architectures. The armeabi-v7a architecture is mostly used by older devices.
Do this by modifying your app's build.gradle file:
android {
(...)
splits {
abi {
enable true
reset()
include 'x86_64', 'arm64-v8a' // Choose what you need.
universalApk false
}
}
(...)
}
Now, when you execute ./gradlew assembleRelease from command line, the following two APKs are generated: app-x86_64-release.apk and app-arm64-v8a-release.apk. Each APK contains only the desired ABI and is therefore much smaller in size. If you change the splits block to set universalApk true, then also a universal APK is generated that contains all ABIs, which is obviously much bigger.
For more information about the splits Gradle block, see Configure Multiple APKs for ABIs.
We recommend to use legacy packaging.
NoteBy default, an APK built with the HERE SDK for release will be around 103 MB or higher - depending on the app features. Therefore, in order to release an app the Play Store, it is required to use either ABI Splits or Android App Bundles (AAB): as of now, the Play Store limits APKs to 100 MB and for ABBs the limit is 150 MB. If you do not want to maintain several APKs built via ABI splits for selected architectures, consider to use ABBs instead.
Map rendering modes
Choose surface or texture view: depending on your application needs, the MapView supports two different native render modes.
- By default,
MapRenderMode.SURFACEis used, which offers the best performance, but may suffer from graphical glitches that may occur on Android 12 and newer. - For applications with complex and dynamic UI or with multiple
MapViewinstances consider to useMapRenderMode.TEXTUREto avoid graphical glitches. This mode may have a greater performance impact than using the defaultSurfaceView.
Choose the MapRenderMode via HereMapOptions.renderMode, which allows to set internally a native SurfaceView or TextureView for rendering.
Adjust the frame rate
By default, the MapView is rendered with 60 frames per second (FPS). Via mapView.get/setFrameRate() the maximum frame rate can be adjusted - for example, to reduce CPU / GPU usage on low end devices. It is also possible to deactivate automatic render cycles by setting FPS to 0. Setting negative values has no effect. The value can be set individually per MapView instance - in case your app contains multiple MapView's.
Another option is to use custom map styles that contain less elements to render.
Protect your credentials
Your credentials should be protected to provide misuse by other parties that are not intended to use them.
One option to keep credentials secure is to store them on a secure server and retrieve them by requests using SSL connections.
For best practice, consider:
- To avoid keeping sensitive data in plain text.
- To transfer credentials using a secure communication channel.
- To store credentials using device security mechanisms and strong encryption ciphers.
- To add anti-tampering and anti-debugging code, so that a potential attacker cannot intercept data during dynamic runtime execution.
- Track the application usage to detect anomalies.
Callbacks and listeners
- The HERE SDK exposes callbacks for single event notification such as for search results.
- For reoccurring event notifications such as for gesture events, listeners are used. When multiple listeners can be set, then the method pattern
add_x()andremove_x()is used as naming convention. If only one listener can be set at a time, the property pattern is used. Set a listener property tonullto stop listening. - It is the responsibility of the developer to handle errors inside the scope of a callback gracefully: As a guideline, code that can throw an exception should be handled.
Use TaskHandles to cancel asynchronous operations
Most asynchronous methods provide a TaskHandle as immediate return value, while the final result of the operation will be returned in a completion handler with a delay. The TaskHandle provides status information and it allows to abort an ongoing operation.
Get access tokens for use with external REST APIs
Each time the HERE SDK is initialized, a new access token is generated internally. In case of multiple SDKNativeEngine instances, each instance holds its own token. You can also refresh and fetch the token via Authentication.authenticate(SDKNativeEngine.getSharedInstance(), callback) where the callback provides the token via authenticationData.token - you can use this token to access external HERE REST APIs.
For using the HERE SDK itself, you do not need to know the token - it is only required under the hood and the HERE SDK is handling the token generation automatically.
To protect our backends against misusage, a rate limit may apply when too many tokens are generated or when too many services are accessed in a too short time frame. In such a case, an engine will respond with a requestLimitReached error or similar. If you expect very high app usage, please talk to your HERE representative upfront to adapt the limits where needed.
Updated yesterday