Sobre as regras de retenção

Quando você ativa a otimização de apps com as configurações padrão, o R8 realiza otimizações extensivas para maximizar os benefícios de performance. O R8 faz modificações substanciais no código, incluindo renomeação, movimentação e remoção de classes, campos e métodos. Se você notar que essas modificações causam erros, especifique quais partes do código o R8 não deve modificar declarando-as em regras de manutenção.

Cenários comuns que exigem regras de retenção

O R8 identifica e preserva todas as chamadas diretas no seu código. No entanto, o R8 não consegue ver usos indiretos de código, o que pode fazer com que ele remova códigos de que seu app precisa, causando falhas. Use regras keep para instruir o R8 a preservar esse código usado indiretamente. Confira algumas situações comuns em que você provavelmente vai precisar de regras de retenção:

  • Código acessado por reflexão: o R8 não consegue identificar quando classes, campos ou métodos são acessados com reflexão. Por exemplo, o R8 não pode identificar um método pesquisado pelo nome usando Class.getDeclaredMethod() ou uma anotação recuperada com Class.getAnnotation(). Nesses casos, o R8 pode renomear ou remover esses métodos e anotações, resultando em um ClassNotFoundException ou um NoSuchMethodException no tempo de execução.
  • Código chamado da Java Native Interface (JNI): quando o código nativo (C ou C++) chama um método Java ou Kotlin, ou quando o código Java ou Kotlin chama o código C++ com JNI, a chamada se baseia em uma pesquisa dinâmica de strings do nome do método. O R8 não consegue ver a chamada de método dinâmica baseada em strings, e, portanto, as otimizações dele podem quebrar seu código.

Esta não é uma lista exaustiva de cenários que exigem regras de retenção, mas eles abrangem a maioria dos casos em que você pode precisar delas.

Como adicionar regras de retenção ao app

Adicione as regras a um arquivo proguard-rules.pro localizado no diretório raiz do módulo do app. O arquivo pode já estar lá, mas, se não estiver, crie um. Para aplicar as regras no arquivo, declare-o no arquivo build.gradle.kts (ou build.gradle) no nível do módulo, conforme mostrado no código a seguir:

Kotlin

android {
    buildTypes {
        release {
            isMinifyEnabled = true
            isShrinkResources = true

            proguardFiles(
                // File with default rules provided by the Android Gradle Plugin
                getDefaultProguardFile("proguard-android-optimize.txt"),

                // File with your custom rules
                "proguard-rules.pro"
            )
           // ...
        }
    }
    // ...
}

Groovy

android {
    buildTypes {
        release {
            minifyEnabled true
            shrinkResources true

            proguardFiles(
                // File with default rules provided by the Android Gradle Plugin
                getDefaultProguardFile('proguard-android-optimize.txt'),

                // File with your custom rules.
                'proguard-rules.pro'
            )
           // ...
        }
    }
    // ...
}

Por padrão, o arquivo de build também inclui o arquivo proguard-android-optimize.txt. Esse arquivo inclui regras necessárias para a maioria dos projetos do Android. Portanto, deixe-o no arquivo de build. Esse arquivo é baseado no arquivo proguard-common.txt e compartilha conteúdo com ele.

Apps maiores geralmente têm código em vários módulos de biblioteca. Nesses casos, é melhor colocar as regras de preservação ao lado do código a que elas se aplicam no módulo de biblioteca específico. A diferença crucial na manutenção de regras de permanência para bibliotecas está em como você declara essas regras no arquivo build.gradle.kts (ou build.gradle) do módulo da biblioteca. Consulte Otimização para autores de bibliotecas para saber mais.

Adicionar uma regra de retenção

Ao adicionar regras de retenção, você pode incluir opções globais e definir suas próprias regras.

  • Opções globais: são diretivas gerais que afetam como o R8 opera em toda a base de código. Para saber mais, consulte Opções globais.
  • Regras de manutenção: elas precisam ser projetadas com cuidado para garantir o equilíbrio certo entre maximizar a otimização do código sem quebrar o app por engano. Para aprender a sintaxe das suas próprias regras de manutenção, consulte Sintaxe das regras de manutenção.

Manter regras para autores de bibliotecas

Depois de aprender sobre as opções globais e a sintaxe das regras de retenção, consulte Otimização para autores de bibliotecas para mais detalhes.