From 648e22a26bed0a49e2a06f01fd5f02b41a72406d Mon Sep 17 00:00:00 2001 From: Krzysztof Borowy Date: Fri, 21 Aug 2020 10:13:17 +0200 Subject: [PATCH 1/3] fix: preventive measures --- android/build.gradle | 5 +++++ .../asyncstorage/AsyncStorageModule.java | 16 +++++++++++++++- .../asyncstorage/ReactDatabaseSupplier.java | 11 +++++++++-- example/android/gradle.properties | 1 + 4 files changed, 30 insertions(+), 3 deletions(-) diff --git a/android/build.gradle b/android/build.gradle index 4dc43dc8..4b990280 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -33,6 +33,10 @@ def useDedicatedExecutor = rootProject.hasProperty('AsyncStorage_dedicatedExecut ? rootProject.properties['AsyncStorage_dedicatedExecutor'] : false +def disableLocalizedCollators = rootProject.hasProperty('AsyncStorage_noLocalizedCollators') + ? rootProject.properties['AsyncStorage_noLocalizedCollators'] + : false + apply plugin: 'com.android.library' android { @@ -43,6 +47,7 @@ android { targetSdkVersion safeExtGet('targetSdkVersion', 28) buildConfigField "Long", "AsyncStorage_db_size", "${dbSizeInMB}L" buildConfigField("boolean", "AsyncStorage_useDedicatedExecutor", "${useDedicatedExecutor}") + buildConfigField("boolean", "AsyncStorage_noLocalizedCollators", "${disableLocalizedCollators}") } lintOptions { abortOnError false diff --git a/android/src/main/java/com/reactnativecommunity/asyncstorage/AsyncStorageModule.java b/android/src/main/java/com/reactnativecommunity/asyncstorage/AsyncStorageModule.java index 0e839319..9936ee50 100644 --- a/android/src/main/java/com/reactnativecommunity/asyncstorage/AsyncStorageModule.java +++ b/android/src/main/java/com/reactnativecommunity/asyncstorage/AsyncStorageModule.java @@ -15,6 +15,7 @@ import com.facebook.react.bridge.Arguments; import com.facebook.react.bridge.Callback; import com.facebook.react.bridge.GuardedAsyncTask; +import com.facebook.react.bridge.LifecycleEventListener; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactContextBaseJavaModule; import com.facebook.react.bridge.ReactMethod; @@ -33,7 +34,7 @@ @ReactModule(name = AsyncStorageModule.NAME) public final class AsyncStorageModule - extends ReactContextBaseJavaModule implements ModuleDataCleaner.Cleanable { + extends ReactContextBaseJavaModule implements ModuleDataCleaner.Cleanable, LifecycleEventListener { // changed name to not conflict with AsyncStorage from RN repo public static final String NAME = "RNC_AsyncSQLiteDBStorage"; @@ -91,6 +92,7 @@ public AsyncStorageModule(ReactApplicationContext reactContext) { AsyncStorageModule(ReactApplicationContext reactContext, Executor executor) { super(reactContext); this.executor = new SerialExecutor(executor); + reactContext.addLifecycleEventListener(this); mReactDatabaseSupplier = ReactDatabaseSupplier.getInstance(reactContext); } @@ -118,6 +120,18 @@ public void clearSensitiveData() { mReactDatabaseSupplier.clearAndCloseDatabase(); } + @Override + public void onHostResume() {} + + @Override + public void onHostPause() {} + + @Override + public void onHostDestroy() { + // ensure we close database when activity is destroyed + mReactDatabaseSupplier.closeDatabase(); + } + /** * Given an array of keys, this returns a map of (key, value) pairs for the keys found, and * (key, null) for the keys that haven't been found. diff --git a/android/src/main/java/com/reactnativecommunity/asyncstorage/ReactDatabaseSupplier.java b/android/src/main/java/com/reactnativecommunity/asyncstorage/ReactDatabaseSupplier.java index 6e191de2..3adcc916 100644 --- a/android/src/main/java/com/reactnativecommunity/asyncstorage/ReactDatabaseSupplier.java +++ b/android/src/main/java/com/reactnativecommunity/asyncstorage/ReactDatabaseSupplier.java @@ -44,6 +44,7 @@ public class ReactDatabaseSupplier extends SQLiteOpenHelper { private Context mContext; private @Nullable SQLiteDatabase mDb; private long mMaximumDatabaseSize = BuildConfig.AsyncStorage_db_size * 1024L * 1024L; + private boolean disableLocalizedCollators = BuildConfig.AsyncStorage_noLocalizedCollators; private ReactDatabaseSupplier(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); @@ -85,7 +86,13 @@ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { if (tries > 0) { deleteDatabase(); } - mDb = getWritableDatabase(); + + if(disableLocalizedCollators) { + String dbPath = mContext.getDatabasePath(DATABASE_NAME).getPath(); + mDb = SQLiteDatabase.openDatabase(dbPath, null, SQLiteDatabase.NO_LOCALIZED_COLLATORS | SQLiteDatabase.OPEN_READWRITE); + } else { + mDb = getWritableDatabase(); + } break; } catch (SQLiteException e) { lastSQLiteException = e; @@ -151,7 +158,7 @@ private synchronized boolean deleteDatabase() { return mContext.deleteDatabase(DATABASE_NAME); } - private synchronized void closeDatabase() { + public synchronized void closeDatabase() { if (mDb != null && mDb.isOpen()) { mDb.close(); mDb = null; diff --git a/example/android/gradle.properties b/example/android/gradle.properties index 6f73824c..db89e011 100644 --- a/example/android/gradle.properties +++ b/example/android/gradle.properties @@ -22,6 +22,7 @@ # Enable dedicated thread pool executor AsyncStorage_dedicatedExecutor=true +AsyncStorage_noLocalizedCollators=true android.useAndroidX=true android.enableJetifier=true From 818f9cc551be769d09d3aca6f2c235f57125fb48 Mon Sep 17 00:00:00 2001 From: Krzysztof Borowy Date: Sun, 27 Sep 2020 12:29:36 +0200 Subject: [PATCH 2/3] fix: drop collation changes According to Android docs, one needs to be consistent when using NO_COLLATION flag with how database was created, so changing this during runtime makes no sense and can lead to some unexpected errors/behaviors (SQLite default collation rule is BINARY). --- android/build.gradle | 5 ----- .../asyncstorage/ReactDatabaseSupplier.java | 14 +++----------- example/android/gradle.properties | 1 - 3 files changed, 3 insertions(+), 17 deletions(-) diff --git a/android/build.gradle b/android/build.gradle index 4b990280..4dc43dc8 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -33,10 +33,6 @@ def useDedicatedExecutor = rootProject.hasProperty('AsyncStorage_dedicatedExecut ? rootProject.properties['AsyncStorage_dedicatedExecutor'] : false -def disableLocalizedCollators = rootProject.hasProperty('AsyncStorage_noLocalizedCollators') - ? rootProject.properties['AsyncStorage_noLocalizedCollators'] - : false - apply plugin: 'com.android.library' android { @@ -47,7 +43,6 @@ android { targetSdkVersion safeExtGet('targetSdkVersion', 28) buildConfigField "Long", "AsyncStorage_db_size", "${dbSizeInMB}L" buildConfigField("boolean", "AsyncStorage_useDedicatedExecutor", "${useDedicatedExecutor}") - buildConfigField("boolean", "AsyncStorage_noLocalizedCollators", "${disableLocalizedCollators}") } lintOptions { abortOnError false diff --git a/android/src/main/java/com/reactnativecommunity/asyncstorage/ReactDatabaseSupplier.java b/android/src/main/java/com/reactnativecommunity/asyncstorage/ReactDatabaseSupplier.java index 3adcc916..0dce878e 100644 --- a/android/src/main/java/com/reactnativecommunity/asyncstorage/ReactDatabaseSupplier.java +++ b/android/src/main/java/com/reactnativecommunity/asyncstorage/ReactDatabaseSupplier.java @@ -7,15 +7,14 @@ package com.reactnativecommunity.asyncstorage; -import javax.annotation.Nullable; - import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteException; import android.database.sqlite.SQLiteOpenHelper; - import com.facebook.common.logging.FLog; import com.facebook.react.common.ReactConstants; +import java.io.File; +import javax.annotation.Nullable; /** * Database supplier of the database used by react native. This creates, opens and deletes the @@ -44,7 +43,6 @@ public class ReactDatabaseSupplier extends SQLiteOpenHelper { private Context mContext; private @Nullable SQLiteDatabase mDb; private long mMaximumDatabaseSize = BuildConfig.AsyncStorage_db_size * 1024L * 1024L; - private boolean disableLocalizedCollators = BuildConfig.AsyncStorage_noLocalizedCollators; private ReactDatabaseSupplier(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); @@ -86,13 +84,7 @@ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { if (tries > 0) { deleteDatabase(); } - - if(disableLocalizedCollators) { - String dbPath = mContext.getDatabasePath(DATABASE_NAME).getPath(); - mDb = SQLiteDatabase.openDatabase(dbPath, null, SQLiteDatabase.NO_LOCALIZED_COLLATORS | SQLiteDatabase.OPEN_READWRITE); - } else { - mDb = getWritableDatabase(); - } + mDb = getWritableDatabase(); break; } catch (SQLiteException e) { lastSQLiteException = e; diff --git a/example/android/gradle.properties b/example/android/gradle.properties index db89e011..6f73824c 100644 --- a/example/android/gradle.properties +++ b/example/android/gradle.properties @@ -22,7 +22,6 @@ # Enable dedicated thread pool executor AsyncStorage_dedicatedExecutor=true -AsyncStorage_noLocalizedCollators=true android.useAndroidX=true android.enableJetifier=true From 7cb8a8ae83fd9034358748b8de58192b47faebf6 Mon Sep 17 00:00:00 2001 From: Krzysztof Borowy Date: Tue, 29 Sep 2020 12:19:53 +0200 Subject: [PATCH 3/3] fix: unused import --- .../reactnativecommunity/asyncstorage/ReactDatabaseSupplier.java | 1 - 1 file changed, 1 deletion(-) diff --git a/android/src/main/java/com/reactnativecommunity/asyncstorage/ReactDatabaseSupplier.java b/android/src/main/java/com/reactnativecommunity/asyncstorage/ReactDatabaseSupplier.java index 0dce878e..c7c59b0e 100644 --- a/android/src/main/java/com/reactnativecommunity/asyncstorage/ReactDatabaseSupplier.java +++ b/android/src/main/java/com/reactnativecommunity/asyncstorage/ReactDatabaseSupplier.java @@ -13,7 +13,6 @@ import android.database.sqlite.SQLiteOpenHelper; import com.facebook.common.logging.FLog; import com.facebook.react.common.ReactConstants; -import java.io.File; import javax.annotation.Nullable; /**