I'm going to make an app that manages the product and bookmark information for each product.
It is being developed using Java, SQLite, and Room. So, the database is stored locally.
Information on products is web-crawled, stored in the Product
Table in the app.db
file, the file is included in the assets folder and the information is made available to users locally using the createFromAsset()
method when the app is distributed. https://developer.android.com/training/data-storage/room/prepopulate
private static AppDatabase create(final Context context) {
return Room.databaseBuilder(context, AppDatabase.class, DB_NAME)
.createFromAsset("database/app.db")
.fallbackToDestructiveMigration()
.allowMainThreadQueries()
.build();
}
And if the web crawling result is changed, I will replace the app.db
file and distribute the app as an updated version.
I want to update the product information when I release a new version of the app, but I want the bookmark information that the user saved locally to remain.
I think two options, but both has a problem.
Save it in the ProductBookmark
table of the app.db
file, the bookmark information will be deleted if the app.db
file is replaced and distributed
Manage bookmark information in a completely different database file, there might be a problem because I cannot establish foreign key relationships between different databases.
How should I manage the bookmark information?
You can use a query to update the table or leave the query blank. use addMigrations method to change table
Room.databaseBuilder(context, AppDatabase.class, DB_NAME)
.createFromAsset("database/app.db")
.addMigrations(MIGRATION_1_2)
.allowMainThreadQueries()
.build();
public static final Migration MIGRATION_1_2 = new Migration(1 , 2) {
@Override
public void migrate(SupportSQLiteDatabase database) {
database.execSQL("SQL COMMAND TO CHANGE SOMETHING ...");
}
};
Here is what you need to do:
(The solution suggests that the user's bookmark information is saved in a separate table, let's say product_bookmarks
on the same database.)
Let's suppose that the database version on the current version of your app is 2. In the new app version, copy a new prepopulated database file in the assets
folder with database version 4. Similarly, change the database version in AppDatabase
to 4.
Now, replace your create()
method with the following:
private static AppDatabase create(Context context) {
return Room.databaseBuilder(
context.getApplicationContext(), AppDatabase.class, DB_NAME)
.createFromAsset("databases/app.db", new PrepackagedDatabaseCallback() {
@Override
public void onOpenPrepackagedDatabase(@NonNull SupportSQLiteDatabase db) {
// Use this callback to restore the data back to database created from
// the new prepopulated database
}
})
.fallbackToDestructiveMigration()
.addMigrations(new Migration(2, 3) {
@Override
public void migrate(@NonNull SupportSQLiteDatabase database) {
// Use this callback to backup user data from product_bookmarks table.
// Store the backup in a member variable in AppDatabase class, e.g.,
// List<ProductBookmark>
}
})
.build();
}
Here is what would happen when this version of your app will be installed:
migrate()
method will be called. Here, you should take backup of user's product bookmark data and store it in a member variable or in a file on device.fallbackToDestructiveMigration()
builder method is called, Room
would drop the database instance on user's device.onOpenPrepackagedDatabase()
will be called. Here, you should restore the user's bookmark data to the newly created database.I haven't tested it myself but you may give it a try and post your feedback here. Hope it helps!
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.