diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Icon.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Icon.java index 2ee17c227d2..8749656e354 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Icon.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Icon.java @@ -36,7 +36,7 @@ public String getId() { * @return The bitmap being used for the icon. */ public Bitmap getBitmap() { - if (mBitmap.getConfig() != Bitmap.Config.ARGB_8888) { + if (mBitmap != null && mBitmap.getConfig() != Bitmap.Config.ARGB_8888) { mBitmap = mBitmap.copy(Bitmap.Config.ARGB_8888, false); } return mBitmap; diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/CameraChangeDispatcher.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/CameraChangeDispatcher.java index cf780dcc3f3..f046744c31a 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/CameraChangeDispatcher.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/CameraChangeDispatcher.java @@ -2,8 +2,7 @@ import android.support.annotation.NonNull; -import java.util.ArrayList; -import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; import static com.mapbox.mapboxsdk.maps.MapboxMap.OnCameraIdleListener; import static com.mapbox.mapboxsdk.maps.MapboxMap.OnCameraMoveCanceledListener; @@ -15,10 +14,10 @@ class CameraChangeDispatcher implements MapboxMap.OnCameraMoveStartedListener, M private boolean idle = true; - private final List onCameraMoveStartedListenerList = new ArrayList<>(); - private final List onCameraMoveCanceledListenerList = new ArrayList<>(); - private final List onCameraMoveListenerList = new ArrayList<>(); - private final List onCameraIdleListenerList = new ArrayList<>(); + private final CopyOnWriteArrayList onCameraMoveStarted = new CopyOnWriteArrayList<>(); + private final CopyOnWriteArrayList onCameraMoveCanceled = new CopyOnWriteArrayList<>(); + private final CopyOnWriteArrayList onCameraMove = new CopyOnWriteArrayList<>(); + private final CopyOnWriteArrayList onCameraIdle = new CopyOnWriteArrayList<>(); private OnCameraMoveStartedListener onCameraMoveStartedListener; private OnCameraMoveCanceledListener onCameraMoveCanceledListener; @@ -58,8 +57,8 @@ public void onCameraMoveStarted(int reason) { } // new API - if (!onCameraMoveStartedListenerList.isEmpty()) { - for (OnCameraMoveStartedListener cameraMoveStartedListener : onCameraMoveStartedListenerList) { + if (!onCameraMoveStarted.isEmpty()) { + for (OnCameraMoveStartedListener cameraMoveStartedListener : onCameraMoveStarted) { cameraMoveStartedListener.onCameraMoveStarted(reason); } } @@ -73,8 +72,8 @@ public void onCameraMove() { } // new API - if (!onCameraMoveListenerList.isEmpty() && !idle) { - for (OnCameraMoveListener cameraMoveListener : onCameraMoveListenerList) { + if (!onCameraMove.isEmpty() && !idle) { + for (OnCameraMoveListener cameraMoveListener : onCameraMove) { cameraMoveListener.onCameraMove(); } } @@ -88,8 +87,8 @@ public void onCameraMoveCanceled() { } // new API - if (!onCameraMoveCanceledListenerList.isEmpty() && !idle) { - for (OnCameraMoveCanceledListener cameraMoveCanceledListener : onCameraMoveCanceledListenerList) { + if (!onCameraMoveCanceled.isEmpty() && !idle) { + for (OnCameraMoveCanceledListener cameraMoveCanceledListener : onCameraMoveCanceled) { cameraMoveCanceledListener.onCameraMoveCanceled(); } } @@ -105,8 +104,8 @@ public void onCameraIdle() { } // new API - if (!onCameraIdleListenerList.isEmpty()) { - for (OnCameraIdleListener cameraIdleListener : onCameraIdleListenerList) { + if (!onCameraIdle.isEmpty()) { + for (OnCameraIdleListener cameraIdleListener : onCameraIdle) { cameraIdleListener.onCameraIdle(); } } @@ -114,42 +113,42 @@ public void onCameraIdle() { } void addOnCameraIdleListener(@NonNull OnCameraIdleListener listener) { - onCameraIdleListenerList.add(listener); + onCameraIdle.add(listener); } void removeOnCameraIdleListener(@NonNull OnCameraIdleListener listener) { - if (onCameraIdleListenerList.contains(listener)) { - onCameraIdleListenerList.remove(listener); + if (onCameraIdle.contains(listener)) { + onCameraIdle.remove(listener); } } void addOnCameraMoveCancelListener(OnCameraMoveCanceledListener listener) { - onCameraMoveCanceledListenerList.add(listener); + onCameraMoveCanceled.add(listener); } void removeOnCameraMoveCancelListener(OnCameraMoveCanceledListener listener) { - if (onCameraMoveCanceledListenerList.contains(listener)) { - onCameraMoveCanceledListenerList.remove(listener); + if (onCameraMoveCanceled.contains(listener)) { + onCameraMoveCanceled.remove(listener); } } void addOnCameraMoveStartedListener(OnCameraMoveStartedListener listener) { - onCameraMoveStartedListenerList.add(listener); + onCameraMoveStarted.add(listener); } void removeOnCameraMoveStartedListener(OnCameraMoveStartedListener listener) { - if (onCameraMoveStartedListenerList.contains(listener)) { - onCameraMoveStartedListenerList.remove(listener); + if (onCameraMoveStarted.contains(listener)) { + onCameraMoveStarted.remove(listener); } } void addOnCameraMoveListener(OnCameraMoveListener listener) { - onCameraMoveListenerList.add(listener); + onCameraMove.add(listener); } void removeOnCameraMoveListener(OnCameraMoveListener listener) { - if (onCameraMoveListenerList.contains(listener)) { - onCameraMoveListenerList.remove(listener); + if (onCameraMove.contains(listener)) { + onCameraMove.remove(listener); } } } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java index de917979aef..1f8faf0231a 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java @@ -365,6 +365,10 @@ public void onStart() { if (mapboxMap != null) { mapboxMap.onStart(); } + + if (mapRenderer != null) { + mapRenderer.onStart(); + } } /** @@ -396,6 +400,11 @@ public void onStop() { // map was destroyed before it was started mapboxMap.onStop(); } + + if (mapRenderer != null) { + mapRenderer.onStop(); + } + ConnectivityReceiver.instance(getContext()).deactivate(); FileSource.getInstance(getContext()).deactivate(); } @@ -407,8 +416,12 @@ public void onStop() { public void onDestroy() { destroyed = true; mapCallback.clearOnMapReadyCallbacks(); - nativeMapView.destroy(); - nativeMapView = null; + + if (nativeMapView != null) { + // null when destroying an activity programmatically mapbox-navigation-android/issues/503 + nativeMapView.destroy(); + nativeMapView = null; + } if (mapRenderer != null) { mapRenderer.onDestroy(); 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 961438ed146..2baff473e94 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 @@ -33,6 +33,10 @@ public MapRenderer(Context context) { nativeInitialize(this, fileSource, pixelRatio, programCacheDir); } + public void onStart() { + // Implement if needed + } + public void onPause() { // Implement if needed } @@ -41,6 +45,10 @@ public void onResume() { // Implement if needed } + public void onStop() { + // Implement if needed + } + public void onDestroy() { // Implement if needed } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/renderer/glsurfaceview/GLSurfaceViewMapRenderer.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/renderer/glsurfaceview/GLSurfaceViewMapRenderer.java index ba2e118faaa..d98e4d06a32 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/renderer/glsurfaceview/GLSurfaceViewMapRenderer.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/renderer/glsurfaceview/GLSurfaceViewMapRenderer.java @@ -31,12 +31,12 @@ public GLSurfaceViewMapRenderer(Context context, GLSurfaceView glSurfaceView) { } @Override - public void onPause() { + public void onStop() { glSurfaceView.onPause(); } @Override - public void onResume() { + public void onStart() { glSurfaceView.onResume(); } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/renderer/textureview/TextureViewMapRenderer.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/renderer/textureview/TextureViewMapRenderer.java index 8cd724a8287..397904b1f58 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/renderer/textureview/TextureViewMapRenderer.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/renderer/textureview/TextureViewMapRenderer.java @@ -74,7 +74,7 @@ public void queueEvent(Runnable runnable) { * {@inheritDoc} */ @Override - public void onPause() { + public void onStop() { renderThread.onPause(); } @@ -82,7 +82,7 @@ public void onPause() { * {@inheritDoc} */ @Override - public void onResume() { + public void onStart() { renderThread.onResume(); } 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 130284e88d2..6a2bf6b07b0 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 @@ -149,8 +149,8 @@ private Handler getHandler() { * * @param callback the callback to be invoked */ - public void listOfflineRegions(@NonNull - final ListOfflineRegionsCallback callback) { + public void listOfflineRegions(@NonNull final ListOfflineRegionsCallback callback) { + fileSource.activate(); listOfflineRegions(fileSource, new ListOfflineRegionsCallback() { @Override @@ -158,6 +158,7 @@ public void onList(final OfflineRegion[] offlineRegions) { getHandler().post(new Runnable() { @Override public void run() { + fileSource.deactivate(); callback.onList(offlineRegions); } }); @@ -168,6 +169,7 @@ public void onError(final String error) { getHandler().post(new Runnable() { @Override public void run() { + fileSource.deactivate(); callback.onError(error); } }); @@ -241,6 +243,7 @@ private boolean isValidOfflineRegionDefinition(OfflineRegionDefinition definitio /** * Changing or bypassing this limit without permission from Mapbox is prohibited * by the Mapbox Terms of Service. + * * @param limit the new tile count limit. */ public native void setOfflineMapboxTileCountLimit(long limit); 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 41dc449b50a..f0cb8d973a6 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 @@ -6,10 +6,8 @@ import android.content.res.AssetManager; import android.os.Environment; import android.support.annotation.NonNull; - import com.mapbox.mapboxsdk.Mapbox; import com.mapbox.mapboxsdk.constants.MapboxConstants; - import timber.log.Timber; /** @@ -119,28 +117,14 @@ public static boolean isExternalStorageReadable() { } private long nativePtr; - private long activeCounter; - private boolean wasPaused; private FileSource(String cachePath, AssetManager assetManager) { initialize(Mapbox.getAccessToken(), cachePath, assetManager); } - public void activate() { - activeCounter++; - if (activeCounter == 1 && wasPaused) { - wasPaused = false; - resume(); - } - } + public native void activate(); - public void deactivate() { - activeCounter--; - if (activeCounter == 0) { - wasPaused = true; - pause(); - } - } + public native void deactivate(); public native void setAccessToken(@NonNull String accessToken); @@ -148,10 +132,6 @@ public void deactivate() { public native void setApiBaseUrl(String baseUrl); - private native void resume(); - - private native void pause(); - /** * Sets a callback for transforming URLs requested from the internet *

diff --git a/platform/android/src/file_source.cpp b/platform/android/src/file_source.cpp index a576661a4f7..6a9d7badb07 100644 --- a/platform/android/src/file_source.cpp +++ b/platform/android/src/file_source.cpp @@ -63,11 +63,22 @@ void FileSource::setResourceTransform(jni::JNIEnv& env, jni::Objectresume(); + if (!activationCounter) { + activationCounter = optional(1) ; + return; + } + + activationCounter.value()++; + if (activationCounter == 1) { + fileSource->resume(); + } } void FileSource::pause(jni::JNIEnv&) { - fileSource->pause(); + activationCounter.value()--; + if (activationCounter == 0) { + fileSource->pause(); + } } jni::Class FileSource::javaClass; @@ -100,8 +111,8 @@ void FileSource::registerNative(jni::JNIEnv& env) { METHOD(&FileSource::setAccessToken, "setAccessToken"), METHOD(&FileSource::setAPIBaseUrl, "setApiBaseUrl"), METHOD(&FileSource::setResourceTransform, "setResourceTransform"), - METHOD(&FileSource::resume, "resume"), - METHOD(&FileSource::pause, "pause") + METHOD(&FileSource::resume, "activate"), + METHOD(&FileSource::pause, "deactivate") ); } diff --git a/platform/android/src/file_source.hpp b/platform/android/src/file_source.hpp index 2933aedf861..194f7846221 100644 --- a/platform/android/src/file_source.hpp +++ b/platform/android/src/file_source.hpp @@ -54,6 +54,7 @@ class FileSource { static void registerNative(jni::JNIEnv&); private: + optional activationCounter; std::unique_ptr> resourceTransform; std::unique_ptr fileSource; }; diff --git a/platform/android/src/run_loop.cpp b/platform/android/src/run_loop.cpp index dff7d1d9845..1d284a9e720 100644 --- a/platform/android/src/run_loop.cpp +++ b/platform/android/src/run_loop.cpp @@ -217,8 +217,10 @@ LOOP_HANDLE RunLoop::getLoopHandle() { } void RunLoop::push(std::shared_ptr task) { - withMutex([&] { queue.push(std::move(task)); }); - impl->wake(); + withMutex([&] { + queue.push(std::move(task)); + impl->wake(); + }); } void RunLoop::run() { diff --git a/platform/android/src/snapshotter/map_snapshotter.cpp b/platform/android/src/snapshotter/map_snapshotter.cpp index 637eb5c1fdc..71f8b4f4c02 100644 --- a/platform/android/src/snapshotter/map_snapshotter.cpp +++ b/platform/android/src/snapshotter/map_snapshotter.cpp @@ -15,7 +15,7 @@ namespace android { MapSnapshotter::MapSnapshotter(jni::JNIEnv& _env, jni::Object _obj, - jni::Object jFileSource, + jni::Object _jFileSource, jni::jfloat _pixelRatio, jni::jint width, jni::jint height, @@ -34,16 +34,16 @@ MapSnapshotter::MapSnapshotter(jni::JNIEnv& _env, return; } - auto& fileSource = mbgl::android::FileSource::getDefaultFileSource(_env, jFileSource); + jFileSource = FileSource::getNativePeer(_env, _jFileSource); + auto& fileSource = mbgl::android::FileSource::getDefaultFileSource(_env, _jFileSource); auto size = mbgl::Size { static_cast(width), static_cast(height) }; auto cameraOptions = position ? CameraPosition::getCameraOptions(_env, position) : CameraOptions(); optional bounds; if (region) { bounds = LatLngBounds::getLatLngBounds(_env, region); } - + showLogo = _showLogo; - // Create the core snapshotter snapshotter = std::make_unique(fileSource, *threadPool, @@ -58,8 +58,9 @@ MapSnapshotter::MapSnapshotter(jni::JNIEnv& _env, MapSnapshotter::~MapSnapshotter() = default; -void MapSnapshotter::start(JNIEnv&) { +void MapSnapshotter::start(JNIEnv& env) { MBGL_VERIFY_THREAD(tid); + activateFilesource(env); snapshotCallback = std::make_unique>( *Scheduler::GetCurrent(), @@ -79,17 +80,19 @@ void MapSnapshotter::start(JNIEnv&) { static auto onSnapshotReady = javaClass.GetMethod)>(*_env, "onSnapshotReady"); javaPeer->Call(*_env, onSnapshotReady, mapSnapshot); } + + deactivateFilesource(*_env); }); snapshotter->snapshot(snapshotCallback->self()); } -void MapSnapshotter::cancel(JNIEnv&) { +void MapSnapshotter::cancel(JNIEnv& env) { MBGL_VERIFY_THREAD(tid); snapshotCallback.reset(); + deactivateFilesource(env); } - void MapSnapshotter::setStyleUrl(JNIEnv& env, jni::String styleURL) { snapshotter->setStyleURL(jni::Make(env, styleURL)); } @@ -108,6 +111,22 @@ void MapSnapshotter::setRegion(JNIEnv& env, jni::Object region) { snapshotter->setRegion(LatLngBounds::getLatLngBounds(env, region)); } +// Private methods // + +void MapSnapshotter::activateFilesource(JNIEnv& env) { + if (!activatedFilesource) { + activatedFilesource = true; + jFileSource->resume(env); + } +} + +void MapSnapshotter::deactivateFilesource(JNIEnv& env) { + if (activatedFilesource) { + activatedFilesource = false; + jFileSource->pause(env); + } +} + // Static methods // jni::Class MapSnapshotter::javaClass; diff --git a/platform/android/src/snapshotter/map_snapshotter.hpp b/platform/android/src/snapshotter/map_snapshotter.hpp index 8cd85060bff..4cdf4bcf2b6 100644 --- a/platform/android/src/snapshotter/map_snapshotter.hpp +++ b/platform/android/src/snapshotter/map_snapshotter.hpp @@ -65,6 +65,11 @@ class MapSnapshotter { std::shared_ptr threadPool; std::unique_ptr> snapshotCallback; std::unique_ptr snapshotter; + + FileSource *jFileSource; + void activateFilesource(JNIEnv&); + void deactivateFilesource(JNIEnv&); + bool activatedFilesource = false; }; } // namespace android diff --git a/platform/darwin/src/run_loop.cpp b/platform/darwin/src/run_loop.cpp index 2ba8f8415bb..d60a88cf52b 100644 --- a/platform/darwin/src/run_loop.cpp +++ b/platform/darwin/src/run_loop.cpp @@ -30,8 +30,10 @@ RunLoop::~RunLoop() { } void RunLoop::push(std::shared_ptr task) { - withMutex([&] { queue.push(std::move(task)); }); - impl->async->send(); + withMutex([&] { + queue.push(std::move(task)); + impl->async->send(); + }); } void RunLoop::run() { diff --git a/platform/default/run_loop.cpp b/platform/default/run_loop.cpp index 6375dba78ec..5bccd21d56c 100644 --- a/platform/default/run_loop.cpp +++ b/platform/default/run_loop.cpp @@ -130,8 +130,10 @@ LOOP_HANDLE RunLoop::getLoopHandle() { } void RunLoop::push(std::shared_ptr task) { - withMutex([&] { queue.push(std::move(task)); }); - impl->async->send(); + withMutex([&] { + queue.push(std::move(task)); + impl->async->send(); + }); } void RunLoop::run() { diff --git a/platform/qt/src/run_loop.cpp b/platform/qt/src/run_loop.cpp index 71ea19032a3..af0c50ebb94 100644 --- a/platform/qt/src/run_loop.cpp +++ b/platform/qt/src/run_loop.cpp @@ -53,8 +53,10 @@ LOOP_HANDLE RunLoop::getLoopHandle() { } void RunLoop::push(std::shared_ptr task) { - withMutex([&] { queue.push(task); }); - impl->async->send(); + withMutex([&] { + queue.push(std::move(task)); + impl->async->send(); + }); } void RunLoop::run() {