I'm trying to copy a pre-populated SQLite database from the assets
folder using Room's createFromAssets
method. The database is sizeable (one table has ~370k entries; about 18mb total size). The database gets created in the databases
folder and it contains the applicable tables, but no data is transferred to the tables.
I've reviewed the following SO questions but haven't found a solution:
- How to pre-populate Room Database from asset?
- Room: Database not created
- How To recreate Room Database From Assets?
- Android Room Library fails to copy database from Asset
- Room: Database not created
I've also reviewed the following informational pages:
- Prepopulate your Room database
- RoomDatabase.Builder
- Packing the Room: pre-populate your database with this one method
- Android Room with a View - Java - Codelab
I've tried waiting several minutes to see if it takes time for the database to populate, but no data ever appears. I've been downloading the database from the virtual device using AS's Device File Explorer and opening it in DB Browser for SQLite, as well as using AS's Database Inspector.
Also, LogCat always displays the following (per logging in MainActivity):
D/MainActivity: onCreate 1st 10 good words NOT FOUND
GoodWordsAndFrequency.db structure:
Table 1 - "bad_words"
Column 1 - "word", TEXT
Table 2 - "english_words"
Column 1 - "id", INTEGER
Column 2 - "word", TEXT
Column 3 - "frequency", INTEGER
app build.gradle dependencies:
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
testImplementation 'junit:junit:4.13.1'
implementation 'androidx.appcompat:appcompat:1.3.1'
implementation 'com.google.android.material:material:1.4.0'
// For Room database
def room_version = "2.3.0"
implementation "androidx.room:room-runtime:$room_version"
annotationProcessor "androidx.room:room-compiler:$room_version"
testImplementation "androidx.room:room-testing:$room_version"
}
ValidWords entity:
import androidx.annotation.NonNull;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.PrimaryKey;
@Entity(tableName = "english_words")
public class ValidWords {
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "id")
public int mID;
@ColumnInfo(name = "word")
@NonNull
public String mWord;
@ColumnInfo(name = "frequency")
public int mFrequency;
public ValidWords(@NonNull String word) {this.mWord = word;}
public String getWord() {return this.mWord;}
public void setWord(@NonNull String word) {this.mWord = word;}
public int getFrequency() {return mFrequency;}
public void setFrequency(int frequency) {this.mFrequency = frequency;}
}
BadWords entity:
import androidx.annotation.NonNull;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.PrimaryKey;
@Entity (tableName = "bad_words")
public class BadWords {
@PrimaryKey
@NonNull
@ColumnInfo(name = "word")
public String mWord;
public BadWords(@NonNull String word) {this.mWord = word;}
@NonNull
public String getWord() {return mWord;}
public void setWord(@NonNull String mWord) {this.mWord = mWord;}
}
wordDAO interface:
import androidx.room.Dao;
import androidx.room.Insert;
import androidx.room.Query;
import java.util.List;
@Dao
public interface wordsDAO {
@Query("SELECT * FROM english_words LIMIT 10")
List<ValidWords> getFirstTenGoodWords();
@Query("SELECT * FROM bad_words")
List<BadWords> getBadWords();
@Query("SELECT * FROM english_words WHERE word LIKE :wordToCheck LIMIT 1")
ValidWords getMatch(String wordToCheck);
@Insert(entity = ValidWords.class)
long insertGoodWordInfo(ValidWords validWord);
}
ReferenceWordsDB database:
import android.content.Context;
import androidx.room.Database;
import androidx.room.Room;
import androidx.room.RoomDatabase;
@Database(entities = {BadWords.class, ValidWords.class}, version = 2)
public abstract class ReferenceWordsDB extends RoomDatabase {
public abstract wordsDAO wordsDAO();
private static volatile ReferenceWordsDB INSTANCE;
static ReferenceWordsDB getDatabase(final Context context){
if (INSTANCE == null){
synchronized (ReferenceWordsDB.class){
if (INSTANCE == null){
INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
ReferenceWordsDB.class, "GoodWordsAndFrequency.db")
.createFromAsset("GoodWordsAndFrequency.db")
.fallbackToDestructiveMigration()
.allowMainThreadQueries()
.build();
}
}
}
return INSTANCE;
}
}
MainActivity:
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.content.res.ResourcesCompat;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
public class MainActivity extends AppCompatActivity {
private static ArrayList<ArrayList<ValidWords>> infoFromFindActualWordRunnableClass;
private final String LOG_CLASS = "MainActivity";
private ReferenceWordsDB wordsDB;
@Override
protected void onCreate(Bundle savedInstanceState) {
final String METHOD = "onCreate";
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getViews();
wordsDB = ReferenceWordsDB.getDatabase(this);
List<ValidWords> first10GoodWords = new ArrayList<>(wordsDB.wordsDAO().getFirstTenGoodWords());
if (first10GoodWords.size() == 0){
Log.d(LOG_CLASS, String.format(Locale.US, "%s 1st 10 good words NOT FOUND", METHOD));
}
for (ValidWords currentWord : first10GoodWords){
Log.d(LOG_CLASS, String.format(Locale.US, "%s currentWord word = %s, frequency = %d", METHOD, currentWord.getWord(), currentWord.getFrequency()));
}
...
}
}
I'm using Android Studio 4.2.2 with all known updates installed.