[android] keep strong callback reference and use application context during cache path change

This commit is contained in:
Łukasz Paczos
2019-05-09 15:06:43 +02:00
committed by Łukasz Paczos
parent e0f32000df
commit 0f599ce804
4 changed files with 71 additions and 51 deletions

View File

@@ -20,7 +20,6 @@ import com.mapbox.mapboxsdk.utils.FileUtils;
import com.mapbox.mapboxsdk.utils.ThreadUtils;
import java.io.File;
import java.lang.ref.WeakReference;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
@@ -69,14 +68,14 @@ public class FileSource {
*
* @param path the path of the current resources cache database
*/
void onSuccess(String path);
void onSuccess(@NonNull String path);
/**
* Receives an error message if setting the path was not successful
*
* @param message the error message
*/
void onError(String message);
void onError(@NonNull String message);
}
@@ -265,63 +264,63 @@ public class FileSource {
/**
* Changes the path of the resources cache database.
* Note that the external storage setting needs to be activated in the manifest.
* <p>
* The callback reference is <b>strongly kept</b> throughout the process,
* so it needs to be wrapped in a weak reference or released on the client side if necessary.
*
* @param context the context of the path
* @param path the new database path
* @param callback the callback to obtain the result
* @deprecated Use {@link #setResourcesCachePath(String, ResourcesCachePathChangeCallback)}
*/
public static void setResourcesCachePath(@NonNull Context context,
@Deprecated
public static void setResourcesCachePath(@NonNull final Context context,
@NonNull final String path,
@NonNull ResourcesCachePathChangeCallback callback) {
final String fileSourceActivatedMessage = "Cannot set path, file source is activated."
+ " Make sure that the map or a resources download is not running.";
if (getInstance(context).isActivated()) {
@NonNull final ResourcesCachePathChangeCallback callback) {
setResourcesCachePath(path, callback);
}
/**
* Changes the path of the resources cache database.
* Note that the external storage setting needs to be activated in the manifest.
* <p>
* The callback reference is <b>strongly kept</b> throughout the process,
* so it needs to be wrapped in a weak reference or released on the client side if necessary.
*
* @param path the new database path
* @param callback the callback to obtain the result
*/
public static void setResourcesCachePath(@NonNull final String path,
@NonNull final ResourcesCachePathChangeCallback callback) {
final Context applicationContext = Mapbox.getApplicationContext();
final FileSource fileSource = FileSource.getInstance(applicationContext);
if (fileSource.isActivated()) {
String fileSourceActivatedMessage = "Cannot set path, file source is activated."
+ " Make sure that the map or a resources download is not running.";
Logger.w(TAG, fileSourceActivatedMessage);
callback.onError(fileSourceActivatedMessage);
} else if (path.equals(resourcesCachePath)) {
} else if (path.equals(getResourcesCachePath(applicationContext))) {
// no need to change the path
callback.onSuccess(path);
} else {
final WeakReference<Context> contextWeakReference = new WeakReference<>(context);
final WeakReference<ResourcesCachePathChangeCallback> callbackWeakReference = new WeakReference<>(callback);
new FileUtils.CheckFileWritePermissionTask(new FileUtils.OnCheckFileWritePermissionListener() {
@Override
public void onWritePermissionGranted() {
final Context context = contextWeakReference.get();
final ResourcesCachePathChangeCallback callback = callbackWeakReference.get();
if (callback == null) {
Logger.w(TAG, "Lost callback reference.");
return;
} else if (context == null) {
String lostContextMessage = "Lost context reference.";
Logger.w(TAG, lostContextMessage);
callback.onError(lostContextMessage);
return;
}
// verify fileSource's activation again after the async task returns
if (getInstance(context).isActivated()) {
Logger.w(TAG, fileSourceActivatedMessage);
callback.onError(fileSourceActivatedMessage);
} else {
final SharedPreferences.Editor editor =
context.getSharedPreferences(MapboxConstants.MAPBOX_SHARED_PREFERENCES, Context.MODE_PRIVATE).edit();
editor.putString(MAPBOX_SHARED_PREFERENCE_RESOURCES_CACHE_PATH, path);
editor.apply();
setResourcesCachePath(context, path);
callback.onSuccess(path);
}
final SharedPreferences.Editor editor =
applicationContext.getSharedPreferences(MapboxConstants.MAPBOX_SHARED_PREFERENCES,
Context.MODE_PRIVATE).edit();
editor.putString(MAPBOX_SHARED_PREFERENCE_RESOURCES_CACHE_PATH, path);
editor.apply();
setResourcesCachePath(applicationContext, path);
callback.onSuccess(path);
}
@Override
public void onError() {
final ResourcesCachePathChangeCallback callback = callbackWeakReference.get();
if (callback != null) {
String message = "Path is not writable: " + path;
Logger.e(TAG, message);
callback.onError(message);
}
String message = "Path is not writable: " + path;
Logger.e(TAG, message);
callback.onError(message);
}
}).execute(new File(path));
}