How to Destroy a Locking Process
In rare cases an Android application using the HERE SDK may crash due to a Storage.LevelDB
error or the initialization of the HERE SDK may fail with a FAILED_TO_LOCK_CACHE_FOLDER
error.
This may happen when a second instance of a SDKNativeEngine
is created with the same access_key_id
as an existing one. Then the local map cache directory is locked by the current process.
This locked cache folder crash can be fixed by adding the following meta-data
tag to the AndroidManifest
file of your app:
<application>
<meta-data
android:name="com.here.sdk.action_on_cache_locked"
android:value="KILL_LOCKING_APP" />
</application>
This tag will check on each application start if a potential cache lock has occurred. If there is a cache lock, this will kill the locking process and the app can start normally. If no cache lock occurred, the code will do nothing. Beside KILL_LOCKING_APP
, also the following values can be set:
-
NO_ACTION
: Nothing will be done. -
WAIT_LOCKING_APP_FINISH
: The app will wait until the locking process has ended. Note that this may happen never.
Additonal Info
Alternatively, the following steps can be taken to prevent the cache lock issue. They have the same effect as the meta-data
tag with KILL_LOCKING_APP
, but require more code and eventually, provide more flexibility:
- Prevent the
InitProvider
of the HERE SDK to be created automatically by adding this to the AndroidManifest.xml
:
<provider
android:name="com.here.sdk.engine.InitProvider"
android:authorities="com.here.sdk.engine.InitProvider"
android:exported="false"
tools:node="remove" />
Note: By default, the InitProvider
is created automatically at application start and the HERE SDK will be initialized and access the cache. This can be deferred by creating the InitProvider
manually - as shown below.
- You may also need to bind the
tools
namespace declaration to the manifest
tag:
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.your_domain.your_app">
- Now you have to manually initialize the HERE SDK and create an
InitProvider
. This needs to be done before any of the HERE SDK functionality is used. For this step you need to write native Java code as explained also here. The first call below will destroy any process of the same application that might still hold a lock on the cache:
long timeoutInMs = 300;
InitProvider.destroyLockingProcess(sdkOptions, timeoutInMs);
InitProvider.initialize(appContext);
SDKOptions sdkOptions = new SDKOptions("YOUR_ACCESS_KEY_ID", "YOUR_ACCESS_KEY_SECRET");
SDKNativeEngine sdkNativeEngine = null;
try {
sdkNativeEngine = new SDKNativeEngine(sdkOptions);
} catch (InstantiationErrorException e) {
}
SDKNativeEngine.setSharedInstance(sdkNativeEngine);
By calling destroyLockingProcess the problem will be gone. You can keep this code to solve sporadic crashes at application start. If no cache lock is detected, destroyLockingProcess()
will do nothing.
Note: By calling SDKNativeEngine.getLockingProcessId(sdkOptions)
, you can get the process ID of the locking process from the Android OS. If no lock occurred, the method will return null
.