I want to use pre-populated database in Android Room. I found a way to make it through using the callback, and filled up the database files. But something is wrong, I'm sure that the database is copied normally, but it remains empty in the device monitor and android emulator. Can you please help me
public abstract class AppDatabase extends RoomDatabase {
private static AppDatabase INSTANCE;
private static final String DB_NAME = "base.db";
static Context ctx;
public abstract Dao dao();
public static AppDatabase getDatabase(Context context) {
if (INSTANCE == null) {
ctx = context;
synchronized (AppDatabase.class) {
if (INSTANCE == null) {
INSTANCE = Room.databaseBuilder(context,
AppDatabase.class, DB_NAME)
.allowMainThreadQueries()
.addCallback(rdc)
.build();
}
}
}
return INSTANCE;
}
private static RoomDatabase.Callback rdc = new RoomDatabase.Callback() {
public void onCreate(SupportSQLiteDatabase db) {
new PopulateDbAsync(INSTANCE, ctx).execute();
Log.d("db create ", "table created when db created first time in onCreate");
}
public void onOpen(@NonNull SupportSQLiteDatabase db) {
ContentValues contentValues = new ContentValues();
}
};
private static class PopulateDbAsync extends AsyncTask<Void, Void, Void> {
private Dao dao;
AssetManager assetManager = ctx.getAssets();
PopulateDbAsync(AppDatabase db, Context context) {
Dao = db.Dao();
ctx = context;
}
@Override
protected Void doInBackground(final Void... params) {
String DB_PATH = "/data/data/mypackage/databases/";
String DB_NAME = "base.db";
try {
Log.d("AppDatabase","Trying copy database file");
OutputStream myOutput = new FileOutputStream(DB_PATH + DB_NAME);
byte[] buffer = new byte[1024];
int length;
InputStream myInput = ctx.getAssets().open("base.db");
while ((length = myInput.read(buffer)) > 0) {
myOutput.write(buffer, 0, length);
}
myInput.close();
myOutput.flush();
myOutput.close();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
}
I solved after spending 6 hours on researching and R & D .
Context is that : - I want to put already existing finaldb.db(which is present inside assests folder) into room database .
Step 1 : copy this framework files from here link
Step 2 : You need to migrate , chill i have code :)
@Database(entities = {Status.class}, version = 1,exportSchema = false)
public abstract class AppDatabase extends RoomDatabase {
public abstract DataDao StatusDao();
private static AppDatabase INSTANCE;
public static AppDatabase getDatabase(Context context) {
if (INSTANCE == null) {
INSTANCE = createDatabase(context);
}
return (INSTANCE);
}
private static final Migration MIGRATION_2_3 = new Migration(1, 2) {
@Override
public void migrate(@NonNull SupportSQLiteDatabase database) {
Log.d("kkkk","bc");
String SQL_CREATE_TABLE = "CREATE TABLE IF NOT EXISTS 'Status' " +
"( 'id' INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT," +
" 'category' TEXT NOT NULL," +
" 'sub_category' TEXT NOT NULL," +
" 'content' TEXT NOT NULL," +
" 'favourite' INTEGER DEFAULT(0))";
database.execSQL(SQL_CREATE_TABLE);
}
};
private static AppDatabase createDatabase(Context context) {
RoomDatabase.Builder<AppDatabase> builder =
Room.databaseBuilder(context.getApplicationContext(), AppDatabase.class,
context.getString(R.string.dbase_name));
return (builder.openHelperFactory(new AssetSQLiteOpenHelperFactory())
.allowMainThreadQueries()
.addMigrations(MIGRATION_2_3)
.build());
}
}
In MIGRATION_2_3 you have to create table exactly same as current database(which is present in assests folder)
want to learn about migration
Step 3 : Now table is created successfully in room database !
In case of crash see your logcat , in which its written in understandable form .