Criar perfis de referência

Você pode gerar perfis automaticamente para cada versão do app usando a biblioteca Macrobenchmark do Jetpack e BaselineProfileRule. Recomendamos usar o com.android.tools.build:gradle:8.1.0 ou versões mais recentes, que vem com melhorias de build para o uso de perfis de referência.

Definir o gerador do perfil de referência

Para criar perfis de referência usando a biblioteca Macrobenchmark, siga estas etapas:

Android Studio Hedgehog Canary 1

Modelo de módulo do gerador de perfil de referência

O modelo de módulo do gerador de perfil de referência do Android Studio automatiza a criação de um novo módulo para gerar e comparar os perfis de referência. A execução do modelo gera a maior parte da configuração do build típica, a geração do perfil de referência e o código de verificação. O modelo cria um código para gerar e comparar perfis de referência e avaliar a inicialização do app.

Você precisa definir manualmente as jornadas ideais do usuário (CUJs) no seu app para que os perfis de referência gerados forneçam as otimizações necessárias para elas.

Criar um módulo do gerador de perfil de referência usando o modelo

Para executar o modelo de módulo do perfil de referência, siga estas etapas:

  1. Selecione File > New > New Module.
  2. Selecione o modelo Baseline Profile Generator no painel Templates e configure-o:
    Figura 1. Modelo de módulo do gerador de perfil de referência.

    Estes são os campos do modelo:

    • Target application: esse campo contém uma lista dos módulos de app no seu projeto e define para qual aplicativo o perfil de referência será gerado. Quando você só tem um módulo de app no seu projeto, há apenas um item nessa lista.
    • Module name: o nome que você quer definir para o módulo do perfil de referência que está criando.
    • Package name: o nome do pacote que você quer para o módulo do perfil de referência.
    • Language: se você quer que o código gerado seja em Kotlin ou Java.
    • Build configuration language: para decidir se você vai usar o script Kotlin (KTS) ou o Groovy nos scripts de configuração do build.
  3. Clique em Finish para que o novo módulo seja criado. Se você estiver usando o controle de origem, talvez receba uma solicitação para adicionar a ee os arquivos do módulo recém-criado.

O módulo recém-criado contém código para gerar e comparar o perfil de referência e testar apenas os tempos básicos de inicialização do app. Recomendamos que você os aumente para incluir as CUJs. Isso vai ajudar na manutenção se você abstrair essas CUJs fora do perfil de referência gerado e do código de referência para que elas possam ser usadas para ambos. Assim, as mudanças nas CUJs são usadas de maneira consistente.

Gerar o perfil de referência

O modelo de módulo do perfil de referência adiciona uma nova configuração de execução para gerar o perfil de referência:

Figura 2. A execução dessa configuração gera o perfil de referência.

Para fazer isso na interface de linha de comando, execute as tarefas :app:generaterBaselineProfile ou :app:generateBaselineProfile do Gradle. Essa ação gera o perfil de referência e o instala no app para o qual um perfil está sendo criado.

Instalar o perfil de referência

Quando a configuração de execução "Gerar perfil de referência" for concluída, ela vai copiar o perfil de referência gerado para src/release/generated/baselineProfiles/baseline-prof.txt no módulo que está sendo criado.

O perfil de referência gerado é criado em build/outputs. No entanto, o caminho completo é determinado pela variante ou variação do app para o qual um perfil está sendo criado e se você usa um dispositivo gerenciado pelo Gradle ou um dispositivo conectado para criar um perfil.

Se você usar os nomes utilizados pelo código e as configurações de build geradas pelo modelo, a criação será feita em build/outputs/managed_device_android_test_additional_output/nonminifiedrelease/pixel6Api31/BaselineProfileGenerator_generate-baseline-prof.txt.

Android Studio Giraffe e versões anteriores

  1. Configure um módulo da Macrobenchmark no seu projeto do Gradle.
  2. Defina um novo teste com o nome BaselineProfileGenerator:
            class BaselineProfileGenerator {
             @get:Rule
                val baselineProfileRule = BaselineProfileRule()
    
                @Test
                fun startup() = baselineProfileRule.collect(
                    packageName = "com.example.app",
                    profileBlock = {
                        startActivityAndWait()
                    }
                )
            }
    

    O gerador pode incluir interações com o app além da inicialização. Isso permite otimizar o desempenho de execução do app, como listas de rolagem, execução de animações e navegação em uma Activity. Confira outros exemplos de testes que usam @BaselineProfileRule para melhorar jornadas ideais do usuário.

  3. (Opcional) Desative a ofuscação ao gerar perfis de referência. Para fazer isso, crie outro arquivo do ProGuard no módulo do app e adicione -dontobfuscate apenas para o tipo de build benchmark, responsável por gerar os perfis.

    Kotlin

    buildTypes {
        val benchmark by creating {
            // Only use benchmark Proguard rules.
            proguardFiles("benchmark-rules.pro")
            // ...
        }
    }
    

    Groovy

    buildTypes {
        benchmark {
            // Only use benchmark Proguard rules.
            proguardFiles 'benchmark-rules.pro'
            // ...
        }
    }
    

Gerar o perfil de referência

Execute o gerador como um teste instrumentado em um dispositivo físico, emulador ou dispositivo gerenciado pelo Gradle com acesso root. Para configurar um dispositivo gerenciado, abra o arquivo build.gradle.kts. No bloco de configuração testOptions, adicione managedDevices e devices e crie uma definição de emulador. Use aosp como systemImageSource, já que você precisa de acesso root ao gerador do perfil de referência.

Kotlin

testOptions {
    managedDevices {
        devices {
            create ("pixel6Api31", ManagedVirtualDevice::class) {
                device = "Pixel 6"
                apiLevel = 31
                systemImageSource = "aosp"
            }
        }
    }
}

Groovy

testOptions {
    managedDevices {
        devices {
            pixel6Api31(com.android.build.api.dsl.ManagedVirtualDevice) {
                device = "Pixel 6"
                apiLevel = 31
                systemImageSource = "aosp"
            }
        }
    }
}

O Gradle cria as tarefas necessárias com base no nome do dispositivo selecionado e nas variantes de build disponíveis no módulo. Ele é formatado como [emulator_name][flavor][build type]AndroidTest. É possível executar essa tarefa em um terminal:

./gradlew :benchmark:pixel6Api31BenchmarkAndroidTest

Comparar o perfil de referência

Para comparar seu perfil de referência, crie uma configuração de execução de teste instrumentado do Android com base na ação de gutter que executa os comparativos de mercado definidos em StartupBenchmarks.kt ou StartupBencharks.java. Para saber mais sobre os testes de comparação, consulte Criar uma classe Macrobenchmark e Automatizar a medição com a biblioteca Macrobenchmark.

Figura 3. Execute os testes do Android na ação de gutter.

Quando essa execução é feita no Android Studio, a saída do build contém detalhes das melhorias de velocidade oferecidas pelo perfil de referência:

StartupBenchmarks_startupCompilationBaselineProfiles
timeToInitialDisplayMs   min 161.8,   median 178.9,   max 194.6
StartupBenchmarks_startupCompilationNone
timeToInitialDisplayMs   min 184.7,   median 196.9,   max 202.9

Capturar todos os caminhos de código necessários

As duas métricas principais dos tempos de inicialização do app são tempo para exibição inicial (TTID, na sigla em inglês) e tempo para exibição total (TTFD, na sigla em inglês). O TTID é o tempo necessário para mostrar o primeiro frame da interface do aplicativo. O TTFD também inclui o tempo para mostrar conteúdo que seja carregado de forma assíncrona após a exibição do frame inicial.

O TTFD é informado quando o método reportFullyDrawn() da ComponentActivity é chamado. Se o método reportFullyDrawn() nunca for chamado, o TTID será informado. Talvez seja necessário atrasar a chamada do reportFullyDrawn() até que o carregamento assíncrono seja concluído. Por exemplo, se a interface tiver uma lista dinâmica, como RecyclerView ou uma lista lenta, talvez ela seja preenchida por uma tarefa em segundo plano concluída depois que a lista for renderizada e, portanto, depois que a interface for marcada como totalmente renderizada. Nesses casos, o código executado depois que a interface atinge o estado totalmente renderizado não é incluído no perfil de referência.

Para incluir o preenchimento da lista como parte do perfil de referência, acesse o FullyDrawnReporter usando getFullyDrawnReporter() e adicione um informante no código do app. Libere o informante depois que a tarefa em segundo plano terminar de preencher a lista. O FullyDrawnReporter não chama o método reportFullyDrawn() até que todos os informantes sejam liberados. Ao fazer isso, o perfil de referência inclui os caminhos de código necessários para preencher a lista. Isso não muda o comportamento do app para o usuário, mas permite que o perfil de referência inclua todos os caminhos de código necessários.

Se o app usar o Jetpack Compose, utilize as APIs abaixo para indicar o estado totalmente renderizado:

  • ReportDrawn indica que o elemento combinável está pronto para interação.
  • ReportDrawnWhen usa um predicado, por exemplo, list.count > 0, para indicar quando o elemento combinável está pronto para interação.
  • ReportDrawnAfter usa um método de suspensão que, quando concluído, indica que o elemento combinável está pronto para interação.

Plug-in para Gradle do perfil de referência

O plug-in para Gradle facilita a geração e a manutenção de perfis de referência. Ele executa as etapas necessárias para gerar e instalar um perfil de referência no módulo do aplicativo.

Para usar o plug-in, adicione um módulo de teste instrumentado ao projeto e defina um conjunto de testes que naveguem pelo app para simular jornadas ideais do usuário. Quando você executa o teste instrumentado, o plug-in para Gradle do perfil de referência monitora todos os métodos e classes executados durante essas jornadas do usuário e gera um perfil de referência com base nesses métodos e classes. Em seguida, ele copia o perfil de referência gerado para o módulo do aplicativo.

O módulo de teste instrumentado é o produtor de perfil. O módulo do app é o consumidor do perfil.

As principais áreas em que você precisa se concentrar são a configuração inicial e a criação de testes para simular as jornadas ideais do usuário.

Requisitos do plug-in

Usar o plug-in

O exemplo abaixo pressupõe a existência de um módulo de aplicativo chamado :app.

Há dois módulos no exemplo abaixo:

  • Consumidor de perfil: o módulo de aplicativo em que o perfil será gerado. No exemplo abaixo, é :app.
  • Produtor de perfil: o módulo de teste do perfil de referência que contém os testes de instrumentação para gerar o perfil. No exemplo abaixo, ele é chamado de :baseline-profile.

Para usar o plug-in, siga estas etapas:

  1. Crie um novo módulo com.android.test, por exemplo, :baseline-profile.
  2. Configure build.gradle para :baseline-profile:
    1. Aplique o plug-in androidx.baselineprofile.
    2. Verifique se targetProjectPath aponta para o módulo :app.
    3. Se quiser, adicione o GMD. No exemplo abaixo, é pixel6Api31. Se não for especificado, o plug-in usará um dispositivo conectado, emulado ou físico.
    4. Aplique a configuração desejada, conforme mostrado no exemplo abaixo.

    Kotlin

    plugins {
        id("com.android.test")
        id("androidx.baselineprofile")
    }
    
    android {
    
        // There are no changes here. It's documented for completeness.
        defaultConfig {
            ...
        }
    
        // This must point to the app module.
        targetProjectPath = ":app"
    
        // This is the optional managed device.
        testOptions.managedDevices.devices {
            pixel6Api31(com.android.build.api.dsl.ManagedVirtualDevice) {
                device = "Pixel 6"
                apiLevel = 31
                systemImageSource = "aosp"
            }
        }
    }
    
    // There are no changes here. It's documented for completeness.
    dependencies { ... }
    
    // This is the plugin configuration. Everything is optional. Defaults are in the
    // comments. In this example, you use the GMD added earlier and disable
    // connected devices.
    baselineProfile {
    
        // This specifies the managed devices to use that you run the tests on. The
        // default is none.
        managedDevices += "pixel6Api31"
    
        // This enables using connected devices to generate profiles. The default is
        // true. When using connected devices, they must be rooted or API 33 and
        // higher.
        useConnectedDevices = false
    }
    

    Groovy

    plugins {
        id 'com.android.test'
        id 'androidx.baselineprofile'
    }
    
    android {
    
        // There are no changes here. It's documented for completeness.
        defaultConfig {
            ...
        }
    
        // This must point to the app module.
        targetProjectPath ':app'
    
        // This is the optional managed device.
        testOptions.managedDevices.devices {
            pixel6Api31(com.android.build.api.dsl.ManagedVirtualDevice) {
                device 'Pixel 6'
                apiLevel 31
                systemImageSource 'aosp'
            }
        }
    }
    
        // There are no changes here. It's documented for completeness.
    dependencies { ... }
    
    // This is the plugin configuration. Everything is optional. Defaults are in the
    // comments. In this example, you use the GMD added earlier and disable
    // connected devices.
    baselineProfile {
    
        // This specifies the managed devices to use that you run the tests on. The
        // default is none.
        managedDevices ['pixel6Api31']
    
        // This enables using connected devices to generate profiles. The default is
        // true. When using connected devices, they must be rooted or API 33 and
        // higher.
        useConnectedDevices false
    }
    
  3. Crie um teste de perfil de referência no módulo de teste :baseline-profile. O exemplo abaixo é um teste que inicia o app e aguarda a inatividade.
  4. Kotlin

    class BaselineProfileGenerator {
    
        @get:Rule
        val baselineRule = BaselineProfileRule()
    
        @Test
        fun startupBaselineProfile() {
            baselineRule.collect("com.myapp") {
                startActivityAndWait()
            }
        }
    }
    

    Java

    public class BaselineProfileGenerator {
    
        @Rule
        Public BaselineProfileRule baselineRule = new BaselineProfileRule();
    
        @Test
        Public void startupBaselineProfile() {
            baselineRule.collect(
                "com.myapp",
                (scope -> {
                    scope.startActivityAndWait();
                    Return Unit.INSTANCE;
                })
            }
        }
    }
    
  5. Atualize a configuração no arquivo build.gradle no módulo do app :app.
    1. Aplique o plug-in androidx.baselineprofile.
    2. Adicione uma dependência de baselineProfile ao módulo :baseline-profile.

    Kotlin

    plugins {
        id("com.android.application")
        id("androidx.baselineprofile")
    }
    
    android {
        // There are no changes to the `android` block.
        ...
    }
    
    dependencies {
        ...
        // Add a baselineProfile dependency to the :baseline-profile module.
        baselineProfile(project(":baseline-profile"))
    }
    

    Groovy

    plugins {
        id 'com.android.application'
        id 'androidx.baselineprofile'
    }
    
    android {
        // No changes to the `android` block.
        ...
    }
    
    dependencies {
        ...
        // Add a baselineProfile dependency to the :baseline-profile module.
        baselineProfile ':baseline-profile"'
    }
    
  6. Gere o perfil executando este código: ./gradlew :app:generateBaselineProfile.

No final da tarefa de geração, o perfil de referência é armazenado em app/src/release/generated/baselineProfiles.

Gerar um perfil de referência para uma biblioteca

No exemplo abaixo, o módulo de biblioteca é :library e o módulo de aplicativo é :sample-app, que contém um app que utiliza a biblioteca.

Neste exemplo, você precisa de três módulos:

  • Destino do app: um módulo de aplicativo que contém um app de exemplo. No exemplo abaixo, é :sample-app.
  • Consumidor de perfil: o módulo de biblioteca para gerar o perfil. No exemplo abaixo, é :library.
  • Produtor de perfil: o módulo de teste do perfil de referência que contém os testes de instrumentação para gerar o módulo.

Para gerar um perfil de referência para uma biblioteca, siga estas etapas:

  1. Crie um novo módulo com.android.test, por exemplo, :baseline-profile.
  2. Configure build.gradle para :baseline-profile:
    1. Aplique o plug-in androidx.baselineprofile.
    2. Confira se targetProjectPath aponta para o módulo :sample-app.
    3. Se quiser, adicione um GMD. No exemplo abaixo, é pixel6Api31.
    4. Aplique a configuração desejada, conforme mostrado no exemplo abaixo.

    Kotlin

    plugins {
        id("com.android.test")
        id("androidx.baselineprofile")
    }
    
    android {
    
        // There are no changes here. It's reported for completeness.
        defaultConfig {
            minSdkVersion 23
            testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        }
    
        // This must point to the app module.
        targetProjectPath = ":app"
    
        // This is the optional managed device.
        testOptions.managedDevices.devices {
            create("pixel6Api31") {
                device = "Pixel 6"
                apiLevel = 31
                systemImageSource = "aosp"
            }
        }
    }
    
    // There's nothing to change here.
    dependencies { ... }
    
    // This is the plugin configuration. Everything is optional. Defaults are in the
    // comments. In this example, you use the GMD added earlier and disable
    // connected devices.
    baselineProfile {
    
        // This specifies the managed devices to use that you run the tests on. The
        // default is none.
        managedDevices += "pixel6Api31"
    
        // This enables using connected devices to generate profiles. The default is
        // true. When using connected devices, they must be rooted or API 33 and
        // higher.
        useConnectedDevices = false
    }
    

    Groovy

    plugins {
        id 'com.android.test'
        id 'androidx.baselineprofile'
    }
    
    android {
    
        // There are no changes here. It's reported for completeness.
        defaultConfig {
            ...
        }
    
        // This must point to the app module.
        targetProjectPath ':app'
    
        // This is the optional managed device.
        testOptions.managedDevices.devices {
            pixel6Api31(com.android.build.api.dsl.ManagedVirtualDevice) {
                device 'Pixel 6'
                apiLevel 31
                systemImageSource 'aosp'
            }
        }
    }
    
    // There's nothing to change here.
    dependencies { ... }
    
    // This is the plugin configuration. Everything is optional. Defaults are in the
    // comments. In this example, you use the GMD added earlier and disable
    // connected devices.
    baselineProfile {
    
        // This specifies the managed devices to use that you run the tests on. The
        // default is none.
        managedDevices ['pixel6Api31']
    
        // This enables using connected devices to generate profiles. The default is
        // true. When using connected devices, they must be rooted or API 33 and
        // higher.
        useConnectedDevices false
    }
    
  3. Crie um teste de perfil de referência no módulo de teste :baseline-profile. Ele precisa ser específico para o app de exemplo e usar todas as funcionalidades da biblioteca.
  4. Atualize a configuração em build.gradle no módulo de biblioteca :library.
    1. Aplique o plug-in androidx.baselineprofile.
    2. Adicione uma dependência de baselineProfile ao módulo :baseline-profile.
    3. Aplique a configuração do plug-in de consumidor que você quer, conforme mostrado no exemplo abaixo.

    Kotlin

    plugins {
        id("com.android.library")
        id("androidx.baselineprofile")
    }
    
    // There are no changes to the android block.
    android { ... }
    
    dependencies {
        ...
        // Add a baselineProfile dependency to the :baseline-profile module.
        baselineProfile(project(":baseline-profile"))
    }
    
    // This is the plugin configuration.
    baselineProfile {
    
        // This filters the generated profile rules. In this example, you keep
        // all the classes in com.library and in all the subpackages.
        filter {
            include "com.mylibrary.**"
        }
    }
    

    Groovy

    plugins {
        id 'com.android.library'
        id 'androidx.baselineprofile'
    }
    
    // There are no changes to the android block.
    android { ... }
    
    dependencies {
        ...
        // Add a baselineProfile dependency to the :baseline-profile module.
        baselineProfile ':baseline-profile'
    }
    
    // This is the plugin configuration.
    baselineProfile {
    
        // This filters the generated profile rules. In this example, you keep
        // all the classes in com.library and in all the subpackages.
        filter {
            include 'com.mylibrary.**'
        }
    }
    
  5. Atualize a configuração em build.gradle no módulo do app :sample-app, adicionando o plug-in androidx.baselineprofile.
  6. Kotlin

    plugins {
        ...
        id("androidx.baselineprofile")
    }
    // There are no other changes to the configuration.
    

    Groovy

    plugins {
        ...
        id 'androidx.baselineprofile'
    }
    // There are no other changes to the configuration.
    
  7. Gere o perfil executando este código: ./gradlew :library:generateBaselineProfile.

No final da tarefa de geração, o perfil de referência é armazenado em library/src/main/generated/baselineProfiles.

DSL

Esta documentação se refere ao plug-in para Gradle do perfil de referência como um plug-in único. Na verdade, há três plug-ins que executam tarefas diferentes, de acordo com o módulo a que são aplicados. O ID do plug-in nesta documentação é androidx.baselineprofile e é um atalho para os três plug-ins.

Para entender melhor esse conceito, consulte os módulos abaixo necessários para gerar um perfil de referência:

  • Um aplicativo para executar os testes de perfil de referência. É um módulo de app Android com com.android.application aplicado. Ao gerar um perfil para uma biblioteca, ele pode ser um app de exemplo. Ao gerar um perfil para um aplicativo, é o próprio aplicativo. No exemplo abaixo, o plug-in androidx.baselineprofile aplica androidx.baselineprofile.apptarget internamente.
  • Um módulo de teste do perfil de referência que contém os testes a serem executados. É um módulo de teste do Android com com.android.test aplicado. No exemplo abaixo, o plug-in androidx.baselineprofile aplica androidx.baselineprofile.producer internamente.
  • Um módulo que consome o perfil de referência no processo de build. É um módulo de app Android com.android.application ou biblioteca com.android.library. No exemplo abaixo, o plug-in androidx.baselineprofile aplica androidx.baselineprofile.consumer internamente.

Destino do app (androidx.baselineprofile.apptarget)

Não há nenhuma configuração.

Produtor de perfil (androidx.baselineprofile.producer)

Suporte para dispositivos gerenciados pelo Gradle

Para utilizar um dispositivo gerenciado pelo Gradle, adicione um na configuração build.gradle do módulo do produtor de perfil, conforme mostrado no exemplo abaixo:

Kotlin

android {
   testOptions.managedDevices.devices {
       create("pixel6Api31") {
           device = "Pixel 6"
           apiLevel = 31
           systemImageSource = "aosp"
       }
   }
}

Groovy

android {
   testOptions.managedDevices.devices {
       pixel6Api31(ManagedVirtualDevice) {
           device 'Pixel 6'
           apiLevel = 31
           systemImageSource 'aosp'
       }
   }
}

Você pode usar o GMD criado para gerar perfis de referência adicionando-o a este código:

Kotlin

baselineProfile {
    managedDevices += "pixel6Api31"
}

Groovy

baselineProfile {
    managedDevices = ['pixel6Api31']
}

Os exemplos abaixo são outras opções disponíveis para ativar ou desativar os dispositivos conectados e gerar perfis de referência:

Kotlin

baselineProfile {
    ...
    useConnectedDevices = true
}

Groovy

baselineProfile {
    ...
    useConnectedDevices true
}

Consumidor de perfil (androidx.baselineprofile.consumer)

Gerar perfis por variação e um para todas as variantes

Você pode gerar perfis por variante, por variação ou como um único arquivo para usar em todas as variantes. É possível controlar esse comportamento usando a configuração de mesclagem, conforme mostrado no exemplo abaixo.

Kotlin

baselineProfile {
    mergeIntoMain = true
}

Groovy

baselineProfile {
    mergeIntoMain true
}
  • Defina mergeIntoMain como true para mesclar todos os perfis gerados para cada variante em um único perfil. Não é possível gerar perfis de referência por variante quando essa configuração é true. Portanto, existe apenas uma tarefa de geração chamada generateBaselineProfile. A saída do perfil é src/main/generated/baselineProfiles.
  • Defina mergeIntoMain como false para desativar a mesclagem e ter um perfil por variante. É possível gerar perfis de referência por variante no exemplo abaixo para que várias tarefas de geração existam, uma por variante. Por exemplo, quando há duas variações, como "sem custos" e "paga", e um tipo de build de lançamento, as tarefas geradas são as seguintes:
    • generateFreeReleaseBaselineProfile
    • generatePaidReleaseBaselineProfile
    • generateReleaseBaselineProfile

Por padrão, essa configuração é true para bibliotecas e false para aplicativos.

Também é possível especificar esse comportamento por variante:

Kotlin

baselineProfile {
    variants {
        freeRelease {
            mergeIntoMain = true
        }
    }
}

Groovy

baselineProfile {
    variants {
        freeRelease {
            mergeIntoMain true
        }
    }
}

No exemplo anterior, as variantes em que a flag está definida como true são mescladas em src/main/generated/baselineProfiles, enquanto os perfis das variantes em que a flag está definida como "false" são mantidos na pasta src/<variant>/generated/baselineProfiles.

Gerar automaticamente o perfil de referência ao criar uma nova versão

É possível acionar manualmente a geração de perfis de referência pela tarefa generateBaselineProfile ou automaticamente ao criar uma versão. Isso é controlado por esta flag:

Kotlin

baselineProfile {
    automaticGenerationDuringBuild = true
}

Groovy

baselineProfile {
    automaticGenerationDuringBuild true
}

Definir essa flag como true aciona um novo perfil de referência a ser gerado para cada versão. Dessa forma, o perfil mais atualizado é incluído no build. Isso significa que executar uma tarefa de criação de build de lançamento, como ./gradlew:app:assembleRelease, também aciona :app:generateReleaseBaselineProfile. Isso também inicia os testes de instrumentação do perfil de referência e cria o build do perfil de referência em que eles são executados. Embora isso ajude a garantir que os usuários recebam o melhor benefício de desempenho, também aumenta o tempo de build devido aos testes duplos de build e instrumentação.

Você também pode especificar esse comportamento por variante, conforme mostrado no exemplo abaixo:

Kotlin

baselineProfile {
    variants {
        freeRelease {
            automaticallyGenerateDuringBuild = true
        }
    }
}

Groovy

baselineProfile {
    variants {
        freeRelease {
            automaticallyGenerateDuringBuild true
        }
    }
}

No exemplo anterior, a tarefa generateFreeReleaseBaselineProfile é executada ao iniciar assembleFreeRelease. Isso ajuda quando o usuário quer ter, por exemplo, um release para o build de distribuição que sempre gera o perfil na criação e um build releaseWithoutProfile para testes internos.

Armazenar perfis de referência em origens

É possível armazenar perfis de referência no diretório de origem usando a flag saveInSrc:

  • true: o perfil de referência é armazenado em src/<variant>/generated/baselineProfiles. Isso permite confirmar o perfil gerado mais recentemente com suas origens.
  • false: o perfil de referência é armazenado nos arquivos intermediários do diretório de build. Dessa forma, ao confirmar seu código, você não salva o perfil gerado mais recentemente.

Kotlin

baselineProfile {
    saveInSrc = true
}

Groovy

baselineProfile {
    saveInSrc true
}

Também é possível especificar esse comportamento por variante:

Kotlin

baselineProfile {
    variants {
        freeRelease {
            saveInSrc = true
        }
    }
}

Groovy

baselineProfile {
    variants {
        freeRelease {
            saveInSrc true
        }
    }
}
Filtrar regras de perfil

É possível filtrar as regras do perfil de referência geradas pela configuração do plug-in. Isso é particularmente útil para bibliotecas se você quiser excluir regras de perfil para classes e métodos que fazem parte de outras dependências do app de exemplo ou da própria biblioteca. Os filtros podem especificar, incluir e excluir pacotes e classes. Quando você especifica apenas exclusões, apenas as regras de perfil de referência correspondentes são excluídas e todo o restante é incluído.

A especificação de filtros pode ser qualquer um destes padrões:

  • O nome do pacote termina com caracteres curinga duplos para corresponder ao pacote especificado e a todos os subpacotes. Por exemplo, com.example.** corresponde a com.example.method e com.example.method.bar.
  • O nome do pacote termina com um caractere curinga e corresponde apenas ao pacote especificado. Por exemplo, com.example.* corresponde a com.example.method, mas não corresponde a com.example.method.bar.
  • Nomes de classe para corresponder a uma classe específica, por exemplo, com.example.MyClass.

Os exemplos abaixo mostram como incluir e excluir pacotes específicos:

Kotlin

baselineProfile {
    filter {
        include("com.somelibrary.widget.grid.**")
        exclude("com.somelibrary.widget.grid.debug.**")
        include("com.somelibrary.widget.list.**")
        exclude("com.somelibrary.widget.list.debug.**")
        include("com.somelibrary.widget.text.**")
        exclude("com.somelibrary.widget.text.debug.**")
    }
}

Groovy

baselineProfile {
    filter {
        include 'com.somelibrary.widget.grid.**'
        exclude 'com.somelibrary.widget.grid.debug.**'
        include 'com.somelibrary.widget.list.**'
        exclude 'com.somelibrary.widget.list.debug.**'
        include 'com.somelibrary.widget.text.**'
        exclude 'com.somelibrary.widget.text.debug.**'
    }
}

Os filtros também oferecem suporte para variantes, que podem ser expressas desta forma:

Kotlin

// Non-specific filters applied to all the variants.
baselineProfile {
    filter { include("com.myapp.**") }
}

// Flavor-specific filters.
baselineProfile {
    variants {
        free {
            filter {
                include("com.myapp.free.**")
            }
        }
        paid {
            filter {
                include("com.myapp.paid.**")
            }
        }
    }
}

// Build-type-specific filters.
baselineProfile {
    variants {
        release {
            filter {
                include("com.myapp.**")
            }
        }
    }
}

// Variant-specific filters.
baselineProfile {
    variants {
        freeRelease {
            filter {
                include("com.myapp.**")
            }
        }
    }
}

Groovy

// Non-specific filters applied to all the variants.
baselineProfile {
    filter { include 'com.myapp.**' }
}

// Flavor-specific filters.
baselineProfile {
    variants {
        free {
            filter {
                include 'com.myapp.free.**'
            }
        }
        paid {
            filter {
                include 'com.myapp.paid.**'
            }
        }
    }
}

// Build-type specific filters.
baselineProfile {
    variants {
        release {
            filter {
                include 'com.myapp.**'
            }
        }
    }
}

// Variant-specific filters.
baselineProfile {
    variants {
        freeRelease {
            filter {
                include 'com.myapp.**'
            }
        }
    }
}

Você também pode filtrar regras usando o argumento filterPredicate em BaselineProfileRule.collect(). Porém, recomendamos usar o plug-in do Gradle para fazer a filtragem, porque ele fornece uma maneira mais simples de filtrar subpacotes e um único local para configurar o módulo todo.

(Opcional) Aplicar manualmente as regras geradas

O gerador do perfil de referência cria um arquivo de texto em formato legível por humanos (HRF, na sigla em inglês) no dispositivo e o copia para a máquina host. Para aplicar o perfil gerado ao código, siga estas etapas:

  1. Localize o arquivo HRF na pasta de build do módulo em que você gera o perfil: [module]/build/outputs/managed_device_android_test_additional_output/[device].

    Os perfis seguem o padrão de nomenclatura [class name]-[test method name]-baseline-prof.txt e têm esta aparência: BaselineProfileGenerator-startup-baseline-prof.txt.

  2. Copie o perfil gerado para a pasta src/flavor/baselineProfiles no módulo do app para uma variação determinada. Para aplicar o perfil a todas as variações, copie-o para src/main/baselineProfiles.

  3. Adicione uma dependência à biblioteca ProfileInstaller no arquivo build.gradle.kts do app para ativar a compilação de perfis de referência locais quando os perfis da nuvem não estiverem disponíveis. Essa é a única maneira de transferir um perfil de referência localmente por sideload.

    dependencies {
         implementation("androidx.profileinstaller:profileinstaller:1.3.1")
    }
    
  4. Crie a versão de produção do app, em que as regras de HRF aplicadas são compiladas no formato binário e incluídas no APK ou AAB. Em seguida, distribua o app normalmente.

.

Outras observações

Ao criar perfis de referência, considere o seguinte:

  • Perfis de referência compilados precisam ter menos de 1,5 MB. Isso não se aplica ao formato de texto nos arquivos de origem, que geralmente são muito maiores antes da compilação. Confira o tamanho do seu perfil de referência binário no artefato de saída em assets/dexopt/baseline.prof para um APK ou em BUNDLE-METADATA/com.android.tools.build.profiles/baseline.prof para um AAB.

  • Regras abrangentes que compilam grande parte do aplicativo podem atrasar a inicialização devido ao aumento do acesso ao disco. Se você estiver começando a usar os perfis de referência, não se preocupe. No entanto, dependendo do seu app e do tamanho e do número de jornadas, adicionar várias delas pode resultar em um desempenho abaixo do ideal. Para avaliar o desempenho do app, teste diferentes perfis e confira se não há uma regressão depois das adições.

  • Se você estiver usando a Proteção automática da integridade, o Google Play vai fazer mudanças no seu APK ou AAB. O Google Play não considera os perfis de referência como parte dessas mudanças. Portanto, os perfis de referência não são compatíveis com a Proteção automática da integridade.

Codelabs

Analise o processo de macrobenchmark para avaliar o desempenho.
Gere um perfil de referência personalizado para um app Android e analise a eficácia dele.