mirror of
https://github.com/status-im/react-native-mapbox-gl.git
synced 2026-08-30 12:31:11 +00:00
Handle succession of offline commands more robustly on Android
This commit is contained in:
+95
-103
@@ -160,21 +160,30 @@ public class ReactNativeMapboxGLModule extends ReactContextBaseJavaModule {
|
||||
|
||||
// Offline packs
|
||||
|
||||
// Offline pack events
|
||||
// Offline pack events and initialization
|
||||
|
||||
class OfflineRegionProgressObserver implements OfflineRegion.OfflineRegionObserver {
|
||||
ReactNativeMapboxGLModule module;
|
||||
OfflineRegion region;
|
||||
OfflineRegionStatus status;
|
||||
String name;
|
||||
boolean recentlyUpdated = false;
|
||||
boolean throttled = true;
|
||||
boolean invalid = false;
|
||||
|
||||
OfflineRegionProgressObserver(ReactNativeMapboxGLModule module, OfflineRegion region) {
|
||||
OfflineRegionProgressObserver(ReactNativeMapboxGLModule module, OfflineRegion region, String name) {
|
||||
this.module = module;
|
||||
this.region = region;
|
||||
if (name == null) {
|
||||
this.name = getOfflineRegionName(region);
|
||||
} else {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
|
||||
void fireUpdateEvent() {
|
||||
if (invalid) { return; }
|
||||
|
||||
recentlyUpdated = true;
|
||||
WritableMap event = serializeOfflineRegionStatus(region, this.status);
|
||||
module.getReactApplicationContext().getJSModule(RCTNativeAppEventEmitter.class)
|
||||
@@ -194,6 +203,8 @@ public class ReactNativeMapboxGLModule extends ReactContextBaseJavaModule {
|
||||
|
||||
@Override
|
||||
public void onStatusChanged(OfflineRegionStatus status) {
|
||||
if (invalid) { return; }
|
||||
|
||||
this.status = status;
|
||||
|
||||
if (!recentlyUpdated) {
|
||||
@@ -205,6 +216,8 @@ public class ReactNativeMapboxGLModule extends ReactContextBaseJavaModule {
|
||||
|
||||
@Override
|
||||
public void onError(OfflineRegionError error) {
|
||||
if (invalid) { return; }
|
||||
|
||||
WritableMap event = Arguments.createMap();
|
||||
event.putString("name", getOfflineRegionName(region));
|
||||
event.putString("error", error.toString());
|
||||
@@ -215,6 +228,8 @@ public class ReactNativeMapboxGLModule extends ReactContextBaseJavaModule {
|
||||
|
||||
@Override
|
||||
public void mapboxTileCountLimitExceeded(long limit) {
|
||||
if (invalid) { return; }
|
||||
|
||||
WritableMap event = Arguments.createMap();
|
||||
event.putString("name", getOfflineRegionName(region));
|
||||
event.putDouble("maxTiles", limit);
|
||||
@@ -222,6 +237,22 @@ public class ReactNativeMapboxGLModule extends ReactContextBaseJavaModule {
|
||||
module.getReactApplicationContext().getJSModule(RCTNativeAppEventEmitter.class)
|
||||
.emit("MapboxOfflineMaxAllowedTiles", event);
|
||||
}
|
||||
|
||||
public void invalidate() {
|
||||
invalid = true;
|
||||
}
|
||||
}
|
||||
|
||||
private int uninitializedObserverCount = -1;
|
||||
private ArrayList<OfflineRegionProgressObserver> offlinePackObservers = new ArrayList<>();
|
||||
private ArrayList<Promise> offlinePackListingRequests = new ArrayList<>();
|
||||
|
||||
void flushListingRequests() {
|
||||
WritableArray result = _getOfflinePacks();
|
||||
for (Promise promise : offlinePackListingRequests) {
|
||||
promise.resolve(result);
|
||||
}
|
||||
offlinePackListingRequests.clear();
|
||||
}
|
||||
|
||||
class OfflineRegionsInitialRequest implements OfflineManager.ListOfflineRegionsCallback {
|
||||
@@ -233,9 +264,26 @@ public class ReactNativeMapboxGLModule extends ReactContextBaseJavaModule {
|
||||
|
||||
@Override
|
||||
public void onList(OfflineRegion[] offlineRegions) {
|
||||
uninitializedObserverCount = offlineRegions.length;
|
||||
for (OfflineRegion region : offlineRegions) {
|
||||
region.setObserver(new OfflineRegionProgressObserver(module, region));
|
||||
final OfflineRegionProgressObserver observer = new OfflineRegionProgressObserver(module, region, null);
|
||||
offlinePackObservers.add(observer);
|
||||
region.setObserver(observer);
|
||||
region.setDownloadState(OfflineRegion.STATE_ACTIVE);
|
||||
region.getStatus(new OfflineRegion.OfflineRegionStatusCallback() {
|
||||
@Override
|
||||
public void onStatus(OfflineRegionStatus status) {
|
||||
observer.onStatusChanged(status);
|
||||
uninitializedObserverCount--;
|
||||
if (uninitializedObserverCount == 0) {
|
||||
flushListingRequests();
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void onError(String error) {
|
||||
Log.e(context.getApplicationContext().getPackageName(), error);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -258,7 +306,7 @@ public class ReactNativeMapboxGLModule extends ReactContextBaseJavaModule {
|
||||
|
||||
}
|
||||
|
||||
// Offline pack listing
|
||||
// Offline pack utils
|
||||
|
||||
static WritableMap serializeOfflineRegionStatus(OfflineRegion region, OfflineRegionStatus status) {
|
||||
WritableMap result = Arguments.createMap();
|
||||
@@ -296,55 +344,14 @@ public class ReactNativeMapboxGLModule extends ReactContextBaseJavaModule {
|
||||
}
|
||||
}
|
||||
|
||||
class OfflineRegionsRequest implements OfflineManager.ListOfflineRegionsCallback {
|
||||
Promise promise;
|
||||
int pendingCount;
|
||||
WritableArray responses;
|
||||
// Offline pack listing
|
||||
|
||||
OfflineRegionsRequest(Promise promise) {
|
||||
this.promise = promise;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onList(OfflineRegion[] offlineRegions) {
|
||||
pendingCount = offlineRegions.length;
|
||||
responses = Arguments.createArray();
|
||||
|
||||
if (pendingCount == 0) {
|
||||
promise.resolve(responses);
|
||||
return;
|
||||
}
|
||||
|
||||
for (OfflineRegion region : offlineRegions) {
|
||||
final OfflineRegion _region = region;
|
||||
final OfflineRegionsRequest _this = this;
|
||||
region.getStatus(new OfflineRegion.OfflineRegionStatusCallback() {
|
||||
@Override
|
||||
public void onStatus(OfflineRegionStatus status) {
|
||||
_this.onStatus(_region, status);
|
||||
}
|
||||
@Override
|
||||
public void onError(String error) {
|
||||
_this.onError(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void onStatus(OfflineRegion region, OfflineRegionStatus status) {
|
||||
WritableMap res = serializeOfflineRegionStatus(region, status);
|
||||
responses.pushMap(res);
|
||||
|
||||
pendingCount--;
|
||||
if (pendingCount == 0) {
|
||||
promise.resolve(responses);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(String error) {
|
||||
promise.reject(new JSApplicationIllegalArgumentException(error));
|
||||
WritableArray _getOfflinePacks() {
|
||||
WritableArray result = Arguments.createArray();
|
||||
for (OfflineRegionProgressObserver observer : offlinePackObservers) {
|
||||
result.pushMap(serializeOfflineRegionStatus(observer.region, observer.status));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
@@ -352,9 +359,7 @@ public class ReactNativeMapboxGLModule extends ReactContextBaseJavaModule {
|
||||
mainHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
OfflineManager.getInstance(context.getApplicationContext()).listOfflineRegions(
|
||||
new OfflineRegionsRequest(promise)
|
||||
);
|
||||
promise.resolve(_getOfflinePacks());
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -436,7 +441,9 @@ public class ReactNativeMapboxGLModule extends ReactContextBaseJavaModule {
|
||||
new OfflineManager.CreateOfflineRegionCallback() {
|
||||
@Override
|
||||
public void onCreate(OfflineRegion offlineRegion) {
|
||||
offlineRegion.setObserver(new OfflineRegionProgressObserver(_this, offlineRegion));
|
||||
OfflineRegionProgressObserver observer = new OfflineRegionProgressObserver(_this, offlineRegion, null);
|
||||
offlinePackObservers.add(observer);
|
||||
offlineRegion.setObserver(observer);
|
||||
offlineRegion.setDownloadState(OfflineRegion.STATE_ACTIVE);
|
||||
promise.resolve(null);
|
||||
}
|
||||
@@ -471,59 +478,44 @@ public class ReactNativeMapboxGLModule extends ReactContextBaseJavaModule {
|
||||
}
|
||||
}
|
||||
|
||||
class OfflineRegionsDeleteRequest implements OfflineManager.ListOfflineRegionsCallback {
|
||||
Promise promise;
|
||||
String name;
|
||||
|
||||
OfflineRegionsDeleteRequest(Promise promise, String name) {
|
||||
this.promise = promise;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onList(OfflineRegion[] offlineRegions) {
|
||||
for (OfflineRegion region : offlineRegions) {
|
||||
String packName = getOfflineRegionName(region);
|
||||
|
||||
if (packName != null && packName.equals(name)) {
|
||||
region.setObserver(new OfflineRegionDummyObserver());
|
||||
region.setDownloadState(OfflineRegion.STATE_INACTIVE);
|
||||
|
||||
final OfflineRegionsDeleteRequest _this = this;
|
||||
region.delete(new OfflineRegion.OfflineRegionDeleteCallback() {
|
||||
@Override
|
||||
public void onDelete() {
|
||||
WritableMap result = Arguments.createMap();
|
||||
result.putString("deleted", _this.name);
|
||||
_this.promise.resolve(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(String error) {
|
||||
_this.onError(error);
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
promise.resolve(Arguments.createMap());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(String error) {
|
||||
promise.reject(new JSApplicationIllegalArgumentException(error));
|
||||
}
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void removeOfflinePack(final String packName, final Promise promise) {
|
||||
mainHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
OfflineManager.getInstance(context.getApplicationContext()).listOfflineRegions(
|
||||
new OfflineRegionsDeleteRequest(promise, packName)
|
||||
);
|
||||
OfflineRegionProgressObserver foundObserver = null;
|
||||
|
||||
for (OfflineRegionProgressObserver observer : offlinePackObservers) {
|
||||
if (packName.equals(observer.name)) {
|
||||
foundObserver = observer;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (foundObserver == null) {
|
||||
promise.resolve(Arguments.createMap());
|
||||
return;
|
||||
}
|
||||
|
||||
offlinePackObservers.remove(foundObserver);
|
||||
foundObserver.invalidate();
|
||||
foundObserver.region.setObserver(new OfflineRegionDummyObserver());
|
||||
foundObserver.region.setDownloadState(OfflineRegion.STATE_INACTIVE);
|
||||
|
||||
final OfflineRegionProgressObserver _foundObserver = foundObserver;
|
||||
foundObserver.region.delete(new OfflineRegion.OfflineRegionDeleteCallback() {
|
||||
@Override
|
||||
public void onDelete() {
|
||||
WritableMap result = Arguments.createMap();
|
||||
result.putString("deleted", _foundObserver.name);
|
||||
promise.resolve(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(String error) {
|
||||
promise.reject(new JSApplicationIllegalArgumentException(error));
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user