O Google tem o compromisso de promover a igualdade racial para as comunidades negras. Saiba como.

Pré-preencher seu banco de dados do Room

Às vezes, você pode querer que seu app comece com um banco de dados que já esteja carregado com um conjunto específico de dados. Isso é chamado de pré-preenchimento de um banco de dados. No Room 2.2.0 e versões posteriores, você pode usar métodos de API para preencher um banco de dados do Room na inicialização com conteúdo de um arquivo de banco de dados pré-empacotado no sistema de arquivos do dispositivo.

Pré-preencher a partir de um recurso de app

Para pré-preencher um banco de dados do Room a partir de um arquivo de banco de dados pré-empacotado localizado em qualquer lugar do assets/ diretório, chame o método createFromAsset() do seu objeto RoomDatabase.Builder antes de chamar build():

Kotlin

    Room.databaseBuilder(appContext, AppDatabase.class, "Sample.db")
        .createFromAsset("database/myapp.db")
        .build()
    

Java

    Room.databaseBuilder(appContext, AppDatabase.class, "Sample.db")
        .createFromAsset("database/myapp.db")
        .build();
    

O método createFromAsset() aceita um argumento de string que contém um caminho relativo do diretório assets/ para o arquivo de banco de dados pré-empacotado.

Pré-preencher automaticamente a partir do sistema de arquivos

Para pré-preencher um banco de dados do Room a partir de um arquivo de banco de dados pré-empacotado localizado em qualquer lugar no sistema de arquivos do dispositivo exceto no diretório assets/ do app, chame o método createFromFile() do seu objeto RoomDatabase.Builder antes de chamar build():

Kotlin

    Room.databaseBuilder(appContext, AppDatabase.class, "Sample.db")
        .createFromFile(File("mypath"))
        .build()
    

Java

    Room.databaseBuilder(appContext, AppDatabase.class, "Sample.db")
        .createFromFile(new File("mypath"))
        .build();
    

O método createFromFile() aceita um argumento File para o arquivo de banco de dados pré-empacotado. O Room cria uma cópia do arquivo designado em vez de abri-lo diretamente. Portanto, verifique se o app tem permissões de leitura no arquivo.

Processar migrações que incluem bancos de dados pré-empacotados

Os arquivos de banco de dados pré-empacotados também podem mudar a maneira como o banco de dados do Room gerencia migrações de substituto. Normalmente, quando as migrações destrutivas são ativadas e o Room precisa realizar uma migração sem um caminho de migração, o Room descarta todas as tabelas no banco de dados e cria um banco de dados vazio com o esquema especificado para a versão de destino. No entanto, se você incluir um arquivo de banco de dados pré-empacotado com o mesmo número da versão de destino, o Room tentará preencher o banco de dados recém-recriado com o conteúdo do arquivo de banco de dados pré-empacotado após a execução da migração destrutiva.

Para mais informações sobre as migrações de banco de dados do Room, consulte Migrating Room databases (link em inglês).

As seções a seguir apresentam alguns exemplos de como isso funciona na prática.

Exemplo: migração de substituto com um banco de dados pré-empacotado

Suponha que:

  • seu app define um banco de dados do Room na versão 3.
  • a instância do banco de dados instalada no dispositivo está na versão 2.
  • há um arquivo de banco de dados pré-empacotado que está na versão 3.
  • não há caminho de migração implementado da versão 2 para a versão 3.
  • as migrações destrutivas estão ativadas.

Kotlin

    // Database class definition declaring version 3.
    @Database(version = 3)
    abstract class AppDatabase : RoomDatabase() {
        ...
    }

    // Destructive migrations are enabled and a prepackaged database
    // is provided.
    Room.databaseBuilder(appContext, AppDatabase.class, "Sample.db")
        .createFromAsset("database/myapp.db")
        .fallbackToDestructiveMigration()
        .build()
    

Java

    // Database class definition declaring version 3.
    @Database(version = 3)
    public abstract class AppDatabase extends RoomDatabase {
        ...
    }

    // Destructive migrations are enabled and a prepackaged database
    // is provided.
    Room.databaseBuilder(appContext, AppDatabase.class, "Sample.db")
        .createFromAsset("database/myapp.db")
        .fallbackToDestructiveMigration()
        .build();
    

Veja o que acontece na seguinte situação:

  1. Como o banco de dados definido no seu app está na versão 3 e a instância do banco de dados já instalada no dispositivo está na versão 2, é necessário fazer uma migração.
  2. Como não há um plano de migração implementado da versão 2 para a versão 3, a migração é uma migração de substituto.
  3. Como o método de criação fallbackToDestructiveMigration() é chamado, a migração de substituto é destrutiva. O Room descarta a instância do banco de dados instalada no dispositivo.
  4. Como há um arquivo do banco de dados pré-empacotado que está na versão 3, o Room recria o banco de dados usando o conteúdo do arquivo pré-empacotado. Por outro lado, se o arquivo do banco de dados pré-empacotado estivesse na versão 2, o Room notaria que ele não corresponde à versão de destino e não o usaria como parte da migração de substituto.

Exemplo: migração de substituto com um banco de dados pré-empacotado

Suponha que seu app implemente um caminho de migração da versão 2 para a versão 3:

Kotlin

    // Database class definition declaring version 3.
    @Database(version = 3)
    abstract class AppDatabase : RoomDatabase() {
        ...
    }

    // Migration path definition from version 2 to version 3.
    val MIGRATION_2_3 = object : Migration(2, 3) {
        override fun migrate(database: SupportSQLiteDatabase) {
            ...
        }
    }

    // A prepackaged database is provided.
    Room.databaseBuilder(appContext, AppDatabase.class, "Sample.db")
        .createFromAsset("database/myapp.db")
        .addMigrations(MIGRATION_2_3)
        .build()
    

Java

    // Database class definition declaring version 3.
    @Database(version = 3)
    public abstract class AppDatabase extends RoomDatabase {
        ...
    }

    // Migration path definition from version 2 to version 3.
    static final Migration MIGRATION_2_3 = new Migration(2, 3) {
        @Override
        public void migrate(SupportSQLiteDatabase database) {
            ...
        }
    };

    // A prepackaged database is provided.
    Room.databaseBuilder(appContext, AppDatabase.class, "Sample.db")
        .createFromAsset("database/myapp.db")
        .addMigrations(MIGRATION_2_3)
        .build();
    

Veja o que acontece na seguinte situação:

  1. Como o banco de dados definido no seu app está na versão 3 e o banco de dados já instalada no dispositivo está na versão 2, é necessário fazer uma migração.
  2. Como há um caminho de migração implementado da versão 2 para a versão 3, o Room executa o método definido migrate() para atualizar a instância do banco de dados no dispositivo para a versão 3, preservando os dados que já estão no banco de dados. O Room não usa o arquivo de banco de dados pré-empacotado, porque ele usa arquivos de banco de dados pré-empacotados apenas no caso de uma migração de substituto.

Exemplo: migração em várias etapas com um banco de dados pré-empacotado

Os arquivos de banco de dados pré-empacotados também podem afetar migrações em várias etapas. Considere o seguinte caso:

  • Seu app define um banco de dados do Room na versão 4.
  • A instância do banco de dados instalada no dispositivo está na versão 2.
  • Há um arquivo de banco de dados pré-empacotado que está na versão 3.
  • Há um caminho de migração implementado da versão 3 para a versão 4, mas não da versão 2 para a versão 3.
  • As migrações destrutivas estão ativadas.

Kotlin

    // Database class definition declaring version 4.
    @Database(version = 4)
    abstract class AppDatabase : RoomDatabase() {
        ...
    }

    // Migration path definition from version 3 to version 4.
    val MIGRATION_3_4 = object : Migration(3, 4) {
        override fun migrate(database: SupportSQLiteDatabase) {
            ...
        }
    }

    // Destructive migrations are enabled and a prepackaged database is
    // provided.
    Room.databaseBuilder(appContext, AppDatabase.class, "Sample.db")
        .createFromAsset("database/myapp.db")
        .addMigrations(MIGRATION_3_4)
        .fallbackToDestructiveMigration()
        .build()
    

Java

    // Database class definition declaring version 4.
    @Database(version = 4)
    public abstract class AppDatabase extends RoomDatabase {
        ...
    }

    // Migration path definition from version 3 to version 4.
    static final Migration MIGRATION_3_4 = new Migration(3, 4) {
        @Override
        public void migrate(SupportSQLiteDatabase database) {
            ...
        }
    };

    // Destructive migrations are enabled and a prepackaged database is
    // provided.
    Room.databaseBuilder(appContext, AppDatabase.class, "Sample.db")
        .createFromAsset("database/myapp.db")
        .addMigrations(MIGRATION_3_4)
        .fallbackToDestructiveMigration()
        .build();
    

Veja o que acontece na seguinte situação:

  1. Como o banco de dados definido no seu app está na versão 4 e a instância do banco de dados já instalada no dispositivo está na versão 2, é necessário fazer uma migração.
  2. Como não há um caminho de migração implementado da versão 2 para a versão 3, a migração é uma migração de substituto.
  3. Como o método de criação fallbackToDestructiveMigration() é chamado, a migração de substituto é destrutiva. O Room descarta a instância do banco de dados no dispositivo.
  4. Como há um arquivo do banco de dados pré-empacotado que está na versão 3, o Room recria o banco de dados usando o conteúdo do arquivo pré-empacotado.
  5. O banco de dados instalado no dispositivo agora está na versão 3. Como essa versão ainda é anterior à versão definida no seu app, é necessário fazer outra migração.
  6. Como há um caminho de migração implementado da versão 3 para a versão 4, o Room executa o método definido migrate() para atualizar a instância do banco de dados no dispositivo para a versão 4, preservando os dados copiados de banco de dados pré-empacotado da versão 3.

Outros recursos

Para saber mais sobre como pré-preencher um banco de dados do Room, consulte os seguintes recursos adicionais.

Vídeos

Blogs