76 votes

Comment utiliser Room Persistence Library avec une base de données préremplie?

J'aimerais utiliser Room avec une base de données pré-remplie, mais je ne comprends pas comment dire à Room où trouver ma base de données.

Je l'ai maintenant mis dans src/main/assets/databases et lorsque je crée l'instance pour la base de données Room, je le crée de cette façon:

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

De cette façon, je pense qu’elle crée une nouvelle base de données à chaque fois, ou de toute façon, qu’elle n’utilise pas la base de données pré-remplie.

Comment puis-je le faire pour trouver ma base de données?

42voto

Alberto Giunta Points 658

C'est comment je l'ai résolu, et comment vous pouvez expédier votre application avec une base de données de population (jusqu'à la Chambre v. alpha5)

  • mettez votre DB SQLite database_name.db dans la assets/databases le dossier

  • prenez les fichiers à partir de ce repo et les mettre dans un package appelé c'est à dire sqlAsset

  • dans votre AppDatabase classe, de modifier votre Salle de DB de création de code en conséquence:

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

Notez que vous devez utiliser "database_name.db" et pas getDatabasePath() ou d'autres méthodes: il a juste besoin du nom du fichier.

31voto

Nishanth Points 908

La solution la plus Simple, sans autres bibliothèques externes.

La chambre s'appuie sur l'existant Android code de la structure pour créer ou ouvrir une base de données. Si vous regardez dans le code source de FrameworkSQLiteOpenHelper (de la Salle de version de l' SQLiteOpenHelper), il appelle en interne SQLiteOpenHelper.getReadableDatabase() et d'autres méthodes où il est nécessaire.

Donc, la solution la plus simple est de copier le fichier de base de données à partir d'actifs répertoire mContext.getDatabasePath("my-database.sqlite") avant la création de la DB avec de la place.

Dans votre cas, le code ressemble à quelque chose comme ça -

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
}

Ce lien a le code nécessaire pour la copie de la DB - lien avec le code

16voto

humazed Points 398

J'avais le même problème alors j'ai créé une bibliothèque qui fait exactement cela. la réponse acceptée fonctionne, mais je pense qu'il est plus facile d'utiliser une bibliothèque.

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

Ajoutez-le à votre build.gradle racine à la fin des référentiels:

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

Ajouter la dépendance

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

vous pouvez trouver la bibliothèque ici: https://github.com/humazed/RoomAsset

1voto

dig Points 1

Solution similaire avec une pièce sans utiliser de bibliothèques externes: 1. Copiez votre base de données dans le dossier des actifs. 2. Copiez votre base de données à partir du dossier des actifs.

 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();
    }
}
 

}

0voto

user6269562 Points 21

vous ne faites que copier assets/databases à app/databases
et que ajoutez addMigrations() en databaseBuilder
il gardera vos données

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X