From 430ce1f97e5a1410e20eb895e7ea266c076537cd Mon Sep 17 00:00:00 2001 From: sspanak Date: Tue, 10 Sep 2024 19:57:46 +0300 Subject: [PATCH] regression: fixed crashing when changing the language soon after starting up --- .../github/sspanak/tt9/db/BaseSyncStore.java | 29 +++++++++++++++++++ .../io/github/sspanak/tt9/db/DataStore.java | 12 ++------ .../sspanak/tt9/db/sqlite/SQLiteOpener.java | 17 ++--------- .../tt9/db/wordPairs/WordPairStore.java | 22 +++++++++++--- .../sspanak/tt9/db/words/WordStore.java | 27 ++++------------- .../github/sspanak/tt9/ime/TraditionalT9.java | 1 - 6 files changed, 56 insertions(+), 52 deletions(-) create mode 100644 app/src/main/java/io/github/sspanak/tt9/db/BaseSyncStore.java diff --git a/app/src/main/java/io/github/sspanak/tt9/db/BaseSyncStore.java b/app/src/main/java/io/github/sspanak/tt9/db/BaseSyncStore.java new file mode 100644 index 00000000..8bde9a79 --- /dev/null +++ b/app/src/main/java/io/github/sspanak/tt9/db/BaseSyncStore.java @@ -0,0 +1,29 @@ +package io.github.sspanak.tt9.db; + +import android.content.Context; + +import io.github.sspanak.tt9.db.sqlite.SQLiteOpener; +import io.github.sspanak.tt9.util.Logger; + +public class BaseSyncStore { + protected SQLiteOpener sqlite; + + protected BaseSyncStore(Context context) { + try { + sqlite = SQLiteOpener.getInstance(context); + sqlite.getDb(); + } catch (Exception e) { + sqlite = null; + Logger.w(getClass().getSimpleName(), "Database connection failure. All operations will return empty results. " + e.getMessage()); + } + } + + protected boolean checkOrNotify() { + if (sqlite == null || sqlite.getDb() == null) { + Logger.e(getClass().getSimpleName(), "No database connection. Cannot query any data."); + return false; + } + + return true; + } +} diff --git a/app/src/main/java/io/github/sspanak/tt9/db/DataStore.java b/app/src/main/java/io/github/sspanak/tt9/db/DataStore.java index 4352b932..576b98a5 100644 --- a/app/src/main/java/io/github/sspanak/tt9/db/DataStore.java +++ b/app/src/main/java/io/github/sspanak/tt9/db/DataStore.java @@ -8,7 +8,6 @@ import androidx.annotation.NonNull; import java.util.ArrayList; import io.github.sspanak.tt9.db.entities.AddWordResult; -import io.github.sspanak.tt9.db.sqlite.SQLiteOpener; import io.github.sspanak.tt9.db.wordPairs.WordPairStore; import io.github.sspanak.tt9.db.words.DictionaryLoader; import io.github.sspanak.tt9.db.words.WordStore; @@ -22,15 +21,8 @@ public class DataStore { public static void init(Context context) { - pairs = pairs == null ? new WordPairStore(context) : pairs; - words = words == null ? new WordStore(context) : words; - } - - - public static void destroy() { - pairs = null; - words = null; - SQLiteOpener.destroyInstance(); + words = words == null ? new WordStore(context.getApplicationContext()) : words; + pairs = pairs == null ? new WordPairStore(context.getApplicationContext()) : pairs; } diff --git a/app/src/main/java/io/github/sspanak/tt9/db/sqlite/SQLiteOpener.java b/app/src/main/java/io/github/sspanak/tt9/db/sqlite/SQLiteOpener.java index 2f14ff91..7f3a446a 100644 --- a/app/src/main/java/io/github/sspanak/tt9/db/sqlite/SQLiteOpener.java +++ b/app/src/main/java/io/github/sspanak/tt9/db/sqlite/SQLiteOpener.java @@ -16,11 +16,11 @@ public class SQLiteOpener extends SQLiteOpenHelper { private static final String LOG_TAG = SQLiteOpener.class.getSimpleName(); private static final String DATABASE_NAME = "tt9.db"; private static final int DATABASE_VERSION = BuildConfig.VERSION_CODE; - private static SQLiteOpener self; - private final ArrayList allLanguages; + private static SQLiteOpener self; private SQLiteDatabase db; + private final ArrayList allLanguages; private SQLiteOpener(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); @@ -38,19 +38,6 @@ public class SQLiteOpener extends SQLiteOpenHelper { } - public static void destroyInstance() { - try { - if (self != null) { - self.close(); - } - } catch (IllegalStateException e) { - Logger.e(LOG_TAG, e.getMessage() + ". Ignoring database state and setting reference to NULL."); - } finally { - self = null; - } - } - - @Override public void onCreate(SQLiteDatabase db) { for (String query : Tables.getCreateQueries(allLanguages)) { diff --git a/app/src/main/java/io/github/sspanak/tt9/db/wordPairs/WordPairStore.java b/app/src/main/java/io/github/sspanak/tt9/db/wordPairs/WordPairStore.java index 02ef5fb1..c419ab1d 100644 --- a/app/src/main/java/io/github/sspanak/tt9/db/wordPairs/WordPairStore.java +++ b/app/src/main/java/io/github/sspanak/tt9/db/wordPairs/WordPairStore.java @@ -10,19 +10,18 @@ import java.util.HashMap; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import io.github.sspanak.tt9.db.BaseSyncStore; import io.github.sspanak.tt9.db.sqlite.DeleteOps; import io.github.sspanak.tt9.db.sqlite.InsertOps; import io.github.sspanak.tt9.db.sqlite.ReadOps; -import io.github.sspanak.tt9.db.sqlite.SQLiteOpener; import io.github.sspanak.tt9.db.words.DictionaryLoader; import io.github.sspanak.tt9.languages.Language; import io.github.sspanak.tt9.preferences.settings.SettingsStore; import io.github.sspanak.tt9.util.Logger; import io.github.sspanak.tt9.util.Timer; -public class WordPairStore { +public class WordPairStore extends BaseSyncStore { // data - private final SQLiteOpener sqlite; private final ConcurrentHashMap> pairs = new ConcurrentHashMap<>(); // timing @@ -33,7 +32,7 @@ public class WordPairStore { public WordPairStore(Context context) { - sqlite = SQLiteOpener.getInstance(context); + super(context); } @@ -92,6 +91,10 @@ public class WordPairStore { public void save() { + if (!checkOrNotify()) { + return; + } + String SAVE_TIMER_NAME = "word_pair_save"; Timer.start(SAVE_TIMER_NAME); @@ -113,6 +116,10 @@ public class WordPairStore { public void load(@NonNull DictionaryLoader dictionaryLoader, ArrayList languages) { + if (!checkOrNotify()) { + return; + } + if (dictionaryLoader.isRunning()) { Logger.e(getClass().getSimpleName(), "Cannot load word pairs while the DictionaryLoader is working."); return; @@ -152,6 +159,10 @@ public class WordPairStore { public void delete(@NonNull ArrayList languages) { + if (!checkOrNotify()) { + return; + } + sqlite.beginTransaction(); for (Language language : languages) { DeleteOps.deleteWordPairs(sqlite.getDb(), language.getId()); @@ -187,4 +198,7 @@ public class WordPairStore { return sb.toString(); } + + + } diff --git a/app/src/main/java/io/github/sspanak/tt9/db/words/WordStore.java b/app/src/main/java/io/github/sspanak/tt9/db/words/WordStore.java index 9237e3c1..adfa2754 100644 --- a/app/src/main/java/io/github/sspanak/tt9/db/words/WordStore.java +++ b/app/src/main/java/io/github/sspanak/tt9/db/words/WordStore.java @@ -6,6 +6,7 @@ import androidx.annotation.NonNull; import java.util.ArrayList; +import io.github.sspanak.tt9.db.BaseSyncStore; import io.github.sspanak.tt9.db.entities.AddWordResult; import io.github.sspanak.tt9.db.entities.NormalizationList; import io.github.sspanak.tt9.db.entities.Word; @@ -13,7 +14,6 @@ import io.github.sspanak.tt9.db.entities.WordList; import io.github.sspanak.tt9.db.sqlite.DeleteOps; import io.github.sspanak.tt9.db.sqlite.InsertOps; import io.github.sspanak.tt9.db.sqlite.ReadOps; -import io.github.sspanak.tt9.db.sqlite.SQLiteOpener; import io.github.sspanak.tt9.db.sqlite.UpdateOps; import io.github.sspanak.tt9.languages.EmojiLanguage; import io.github.sspanak.tt9.languages.Language; @@ -24,21 +24,14 @@ import io.github.sspanak.tt9.util.Text; import io.github.sspanak.tt9.util.Timer; -public class WordStore { +public class WordStore extends BaseSyncStore { private final String LOG_TAG = "sqlite.WordStore"; - - private SQLiteOpener sqlite = null; - private ReadOps readOps = null; + private final ReadOps readOps; public WordStore(@NonNull Context context) { - try { - sqlite = SQLiteOpener.getInstance(context); - sqlite.getDb(); - readOps = new ReadOps(); - } catch (Exception e) { - Logger.w(LOG_TAG, "Database connection failure. All operations will return empty results. " + e.getMessage()); - } + super(context); + readOps = new ReadOps(); } @@ -193,16 +186,6 @@ public class WordStore { } - private boolean checkOrNotify() { - if (sqlite == null || sqlite.getDb() == null) { - Logger.e(LOG_TAG, "No database connection. Cannot query any data."); - return false; - } - - return true; - } - - public void makeTopWord(@NonNull Language language, @NonNull String word, @NonNull String sequence) { if (!checkOrNotify() || word.isEmpty() || sequence.isEmpty() || language instanceof NullLanguage) { return; diff --git a/app/src/main/java/io/github/sspanak/tt9/ime/TraditionalT9.java b/app/src/main/java/io/github/sspanak/tt9/ime/TraditionalT9.java index aa0f702f..d25cb02b 100644 --- a/app/src/main/java/io/github/sspanak/tt9/ime/TraditionalT9.java +++ b/app/src/main/java/io/github/sspanak/tt9/ime/TraditionalT9.java @@ -194,7 +194,6 @@ public class TraditionalT9 extends MainViewHandler { requestHideSelf(0); onStop(); backgroundTasks.removeCallbacksAndMessages(null); - DataStore.destroy(); stopSelf(); }