Java 如何使用Android Room创建和预填充sqlite数据库文件?

Java 如何使用Android Room创建和预填充sqlite数据库文件?,java,android,database,android-room,Java,Android,Database,Android Room,我想创建sqlite数据库文件DatabaseName.db,当我尝试执行下面的代码段时,应该在应用程序路径(/data/data/MyApplicationName/databases/DatabaseName.db)中创建几个实体,但是DatabaseName.db文件不在那里。为什么? MyDatabaseSample db = Room.databaseBuilder(context, MyClass.class,

我想创建sqlite数据库文件DatabaseName.db,当我尝试执行下面的代码段时,应该在应用程序路径(/data/data/MyApplicationName/databases/DatabaseName.db)中创建几个实体,但是DatabaseName.db文件不在那里。为什么?

MyDatabaseSample db = Room.databaseBuilder(context,
                     MyClass.class,
                     "DatabaseName.db")
    .addCallback(new RoomDatabase.Callback() {
    @Override
    public void onCreate(@NonNull SupportSQLiteDatabase ssdb) {
        super.onCreate(db);
        Log.d(TAG, "Database created - populate database");
    }).build();
仅当我创建实体对象的实例并在获取数据库引用后立即将其插入数据库时,才会在应用程序路径中创建数据库。因为我想在数据库创建之后预填充数据库,所以我认为在回调的onCreate方法中进行预填充是有意义的,但onCreate永远不会被调用。因此,如何创建包含所有表示实体的表的“DatabaseName.db”文件,并使用回调填充数据库?


OBS:我正在使用Room版本use 1.1.0-alpha2,并使用SDK android API 27进行编译

我认为您需要在预填充数据库之前定义一些,这就是我所做的,它的工作与预期的一样,以下是我到目前为止所做的一些代码:

public class DatabaseCreator {

    private static MyDatabaseSample appDatabase;
    private static final Object LOCK = new Object();

    public synchronized static MyDatabaseSample getDBInstance(final Context context){
        if(appDatabase == null) {
            synchronized (LOCK) {
                if (appDatabase == null) {
                    RoomDatabase.Callback appDBCallback = new RoomDatabase.Callback() {
                        @Override
                        public void onCreate(@NonNull SupportSQLiteDatabase db) {
                            super.onCreate(db);
                            try {
                                ReadScript.insertFromFile(context, R.raw.populate_db, db);
                            } catch (IOException e) {
                                Log.d("DB Population Error", e.toString());
                            }
                        }
                    };
                    appDatabase = Room.databaseBuilder(context,
                            MyDatabaseSample.class, "DatabaseName").addCallback(appDBCallback).build();
                }
            }
        }
        return appDatabase;
    }
}
上面的代码是一个单例,它使用回调的onCreate来使用“原始资源”(要将原始资源添加到项目中,只需在res文件夹中创建一个包含sql脚本的文件夹,如“res/raw”)。要阅读脚本,我使用了以下代码:

public class ReadScript {
    public static int insertFromFile(Context context, int resourceCode, SupportSQLiteDatabase db) throws IOException {
        // Reseting Counter
        int result = 0;

        // Open the resource
        InputStream insertsStream = context.getResources().openRawResource(resourceCode);
        BufferedReader insertReader = new BufferedReader(new InputStreamReader(insertsStream));

        // Iterate through lines (assuming each insert has its own line and theres no other stuff)
        while (insertReader.ready()) {
            String insertStmt = insertReader.readLine();
            if(insertStmt != null){
                if(insertStmt.isEmpty()) continue;
                db.execSQL(insertStmt);
                result++;
                Log.d("Statement #", Integer.toString(result));
            }
        }
        insertReader.close();

        // returning number of inserted rows
        return result;
    }
}
然后您只需通过以下操作创建db实例:

MyDatabaseSample db = DatabaseCreator.getDBInstance(getContext());
注意:您可以尝试在原始脚本中创建表,但我还没有尝试过


祝你好运。

谢谢Basher SG,但仍然没有从回调执行onCreate方法。仅当我使用db引用并在回调外部插入一个元组时,它才起作用,但在回调外部插入元组以通过回调填充数据库的其余部分是很奇怪的。