web-dev-qa-db-ja.com

事前設定されたデータベースでRoom Persistence Libraryを使用する方法は?

事前に入力されたデータベースでRoomを使用したいのですが、データベースの場所をRoomに伝える方法がわかりません。

これをsrc/main/assets/databasesに配置し、Roomデータベースのインスタンスを作成するときに、次のように作成します。

Room.databaseBuilder(
    getApplicationContext(),
    AppDatabase.class,
    "justintrain.db"
)
.allowMainThreadQueries()
.build();

このように、毎回新しいデータベースを作成していると思います。とにかく、事前に作成されたデータベースを使用しているわけではありません。

データベースを見つけるにはどうすればよいですか?

57
Alberto Giunta

これが私がそれを解決した方法であり、事前に入力されたデータベースを使用してアプリケーションを出荷する方法です(Room v。alpha5まで)

  • sQLite DB database_name.dbassets/databasesフォルダーに入れます

  • ファイルを取得します このレポジトリから そしてそれらをi.e.という名前のパッケージに入れますsqlAsset

  • AppDatabaseクラスで、それに応じてルームのDB作成コードを変更します。

    Room.databaseBuilder(context.getApplicationContext(), 
                         AppDatabase.class, 
                         "database_name.db")
    .openHelperFactory(new AssetSQLiteOpenHelperFactory())
    .allowMainThreadQueries()
    .build();
    

getDatabasePath()またはその他のメソッドではなく、"database_name.db"を使用する必要があることに注意してください。ファイルの名前が必要なだけです。

35
Alberto Giunta

他の外部ライブラリを使用しないシンプルなソリューション。

ルームは、既存のAndroidフレームワークコードに依存してデータベースを作成または開きます。 FrameworkSQLiteOpenHelper(ルームのSQLiteOpenHelperのバージョン)のソースコードを調べると、必要に応じてSQLiteOpenHelper.getReadableDatabase()およびその他のメソッドを内部的に呼び出します。

したがって、最も簡単な解決策は、RoomでDBを作成する前に、アセットファイルからmContext.getDatabasePath("my-database.sqlite")にDBファイルをコピーするだけです。

あなたの場合、コードは次のようになります-

private final String DB_NAME = "my-database.sqlite";

private MyDatabase buildDatabase(Context context) {
    final File dbFile = context.getDatabasePath(DB_NAME);

    if(!dbFile.exists()) {
        copyDatabaseFile(dbFile.getAbsolutePath());
    }

    return Room.databaseBuilder(context.getApplicationContext(),
        MyDatabase.class, DB_NAME)
        .build();
}

private void copyDatabaseFile(String destinationPath) {
    // code to copy the file from assets/database directory to destinationPath
}

このリンクには、DBをコピーするために必要なコードがあります- コード付きリンク

19
Nishanth

私は同じ問題を抱えていたので、まさにそれを行うライブラリを作成しました。受け入れられた答えは動作しますが、ライブラリを使用する方が簡単だと思います。

AppDatabase db = RoomAsset
    .databaseBuilder(context.getApplicationContext(), AppDatabase.class, "database_name.db")
    .build(); 

リポジトリの最後でルートbuild.gradleに追加します。

allprojects {
    repositories {
        ...
        maven { url "https://jitpack.io" }
    }
}

依存関係を追加する

dependencies {
    // ... other dependencies
    implementation 'com.github.humazed:RoomAsset:v1.0'
}

ライブラリはここで見つけることができます: https://github.com/humazed/RoomAsset

16
humazed

assets/databasesapp/databasesにコピーするだけです
そしてdatabaseBuilderaddMigrations()を追加するより
データを保持します

0
user6269562

外部ライブラリを使用しない部屋のある同様のソリューション:1.データベースを資産フォルダーにコピーします2.データベースを資産フォルダーからコピーします

public class MainActivity extends AppCompatActivity {

public static AppDatabase db;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    copyDatabase(getApplicationContext(), "yourdatabase.db");

    db = Room.databaseBuilder(getApplicationContext(), .class, "yourdatabase.db").allowMainThreadQueries().build();
}

private void copyDatabase(Context context, String databaseName) {
    final File dbPath = context.getDatabasePath(databaseName);

    // If the database already exists, return
    if (dbPath.exists()) {
        Log.d("Activity", "db Path Exists");
        return;
    }

    // Make sure we have a path to the file
    dbPath.getParentFile().mkdirs();

    // Try to copy database file
    try {
        final InputStream inputStream = context.getAssets().open(databaseName);
        final OutputStream output = new FileOutputStream(dbPath);

        byte[] buffer = new byte[8192];
        int length;

        while ((length = inputStream.read(buffer, 0, 8192)) > 0) {
            output.write(buffer, 0, length);
        }

        output.flush();
        output.close();
        inputStream.close();
    }
    catch (IOException e) {
        Log.d("Activity", "Failed to open file", e);
        e.printStackTrace();
    }
}

}

0
dig