From aee5c7ea766609b8850471750770778f8ee0a1fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Thu, 16 Aug 2018 15:37:38 +0200 Subject: [android] obtain paths to file directories on a worker thread --- .../src/main/java/com/mapbox/mapboxsdk/Mapbox.java | 5 + .../mapboxsdk/maps/renderer/MapRenderer.java | 2 +- .../mapbox/mapboxsdk/offline/OfflineManager.java | 2 +- .../mapboxsdk/snapshotter/MapSnapshotter.java | 2 +- .../com/mapbox/mapboxsdk/storage/FileSource.java | 104 ++++++++++++++++++++- 5 files changed, 107 insertions(+), 8 deletions(-) diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/Mapbox.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/Mapbox.java index 6897cf66df..8c9cd362d3 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/Mapbox.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/Mapbox.java @@ -11,6 +11,9 @@ import com.mapbox.mapboxsdk.constants.MapboxConstants; import com.mapbox.mapboxsdk.exceptions.MapboxConfigurationException; import com.mapbox.mapboxsdk.maps.Telemetry; import com.mapbox.mapboxsdk.net.ConnectivityReceiver; +import com.mapbox.mapboxsdk.storage.FileSource; +import com.mapbox.mapboxsdk.utils.ThreadUtils; + import timber.log.Timber; /** @@ -42,8 +45,10 @@ public final class Mapbox { */ @UiThread public static synchronized Mapbox getInstance(@NonNull Context context, @Nullable String accessToken) { + ThreadUtils.checkThread("Mapbox"); if (INSTANCE == null) { Context appContext = context.getApplicationContext(); + FileSource.initializeFileDirsPaths(appContext); INSTANCE = new Mapbox(appContext, accessToken); if (isAccessTokenValid(accessToken)) { initializeTelemetry(); diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/renderer/MapRenderer.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/renderer/MapRenderer.java index 1129b8000e..492f653dae 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/renderer/MapRenderer.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/renderer/MapRenderer.java @@ -28,7 +28,7 @@ public abstract class MapRenderer implements MapRendererScheduler { public MapRenderer(Context context, String localIdeographFontFamily) { FileSource fileSource = FileSource.getInstance(context); float pixelRatio = context.getResources().getDisplayMetrics().density; - String programCacheDir = context.getCacheDir().getAbsolutePath(); + String programCacheDir = FileSource.getInternalCachePath(context); // Initialise native peer nativeInitialize(this, fileSource, pixelRatio, programCacheDir, localIdeographFontFamily); diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineManager.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineManager.java index dbf425986d..f6dd7ff7a1 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineManager.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineManager.java @@ -109,7 +109,7 @@ public class OfflineManager { @Override public void run() { try { - String path = context.getCacheDir().getAbsolutePath() + File.separator + "mbgl-cache.db"; + String path = FileSource.getInternalCachePath(context) + File.separator + "mbgl-cache.db"; File file = new File(path); if (file.exists()) { file.delete(); diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/snapshotter/MapSnapshotter.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/snapshotter/MapSnapshotter.java index 2aea565d8b..354a8fb6cd 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/snapshotter/MapSnapshotter.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/snapshotter/MapSnapshotter.java @@ -217,7 +217,7 @@ public class MapSnapshotter { checkThread(); this.context = context.getApplicationContext(); FileSource fileSource = FileSource.getInstance(context); - String programCacheDir = context.getCacheDir().getAbsolutePath(); + String programCacheDir = FileSource.getInternalCachePath(context); nativeInitialize(this, fileSource, options.pixelRatio, options.width, options.height, options.styleUrl, options.styleJson, options.region, options.cameraPosition, diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/storage/FileSource.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/storage/FileSource.java index c8d02c05d9..495e425976 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/storage/FileSource.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/storage/FileSource.java @@ -4,6 +4,7 @@ import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.res.AssetManager; +import android.os.AsyncTask; import android.os.Environment; import android.support.annotation.Keep; import android.support.annotation.NonNull; @@ -11,6 +12,10 @@ import android.support.annotation.UiThread; import com.mapbox.mapboxsdk.Mapbox; import com.mapbox.mapboxsdk.constants.MapboxConstants; +import com.mapbox.mapboxsdk.utils.ThreadUtils; + +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; import timber.log.Timber; @@ -20,6 +25,11 @@ import timber.log.Timber; */ public class FileSource { + private static String resourcesCachePath; + private static String internalCachePath; + private static final Lock resourcesCachePathLoaderLock = new ReentrantLock(); + private static final Lock internalCachePathLoaderLock = new ReentrantLock(); + /** * This callback allows implementors to transform URLs before they are requested * from the internet. This can be used add or remove custom parameters, or reroute @@ -51,19 +61,20 @@ public class FileSource { @UiThread public static synchronized FileSource getInstance(Context context) { if (INSTANCE == null) { - String cachePath = getCachePath(context); - INSTANCE = new FileSource(cachePath, context.getResources().getAssets()); + INSTANCE = new FileSource(getResourcesCachePath(context), context.getResources().getAssets()); } return INSTANCE; } /** - * Get the cache path for a context. + * Get files directory path for a context. * - * @param context the context to derive the cache path from - * @return the cache path + * @param context the context to derive the files directory path from + * @return the files directory path + * @deprecated Use {@link #getResourcesCachePath(Context)} instead. */ + @Deprecated public static String getCachePath(Context context) { // Default value boolean setStorageExternal = MapboxConstants.DEFAULT_SET_STORAGE_EXTERNAL; @@ -122,6 +133,89 @@ public class FileSource { return false; } + /** + * Initializes file directories paths. + * + * @param context the context to derive paths from + */ + @UiThread + public static void initializeFileDirsPaths(Context context) { + ThreadUtils.checkThread("FileSource"); + lockPathLoaders(); + if (resourcesCachePath == null || internalCachePath == null) { + new FileDirsPathsTask().execute(context); + } + } + + private static class FileDirsPathsTask extends AsyncTask { + + @Override + protected void onCancelled() { + unlockPathLoaders(); + } + + @Override + protected String[] doInBackground(Context... contexts) { + return new String[] { + getCachePath(contexts[0]), + contexts[0].getCacheDir().getAbsolutePath() + }; + } + + @Override + protected void onPostExecute(String[] paths) { + resourcesCachePath = paths[0]; + internalCachePath = paths[1]; + unlockPathLoaders(); + } + } + + /** + * Get files directory path for a context. + * + * @param context the context to derive the files directory path from + * @return the files directory path + */ + public static String getResourcesCachePath(Context context) { + resourcesCachePathLoaderLock.lock(); + try { + if (resourcesCachePath == null) { + resourcesCachePath = getCachePath(context); + } + return resourcesCachePath; + } finally { + resourcesCachePathLoaderLock.unlock(); + } + } + + /** + * Get internal cache path for a context. + * + * @param context the context to derive the internal cache path from + * @return the internal cache path + */ + public static String getInternalCachePath(Context context) { + internalCachePathLoaderLock.lock(); + try { + if (internalCachePath == null) { + internalCachePath = context.getCacheDir().getAbsolutePath(); + } + return internalCachePath; + } finally { + internalCachePathLoaderLock.unlock(); + } + } + + private static void lockPathLoaders() { + internalCachePathLoaderLock.lock(); + resourcesCachePathLoaderLock.lock(); + } + + private static void unlockPathLoaders() { + resourcesCachePathLoaderLock.unlock(); + internalCachePathLoaderLock.unlock(); + } + @Keep private long nativePtr; -- cgit v1.2.1