Usar regras para resolver problemas de otimização

Além das regras de retenção gerais, dos tipos de regras de retenção adicionais e das opções globais, você pode usar determinadas regras para resolver problemas na sua otimização.

-checkdiscard

A regra -checkdiscard permite verificar se o R8 descartou uma classe ou um membro que você esperava que fosse removido. Se a classe ou o membro especificado não for descartado, a build vai falhar.

A sintaxe de -checkdiscard é a seguinte:


-checkdiscard <class_specification>

No exemplo a seguir, a build falha se o campo userId ou o método setLabel() da classe com.example.models.User for mantido:

-checkdiscard class com.example.models.User{
  private java.lang.String userId;
  public void setLabel(java.lang.String);
}

O código da classe ainda pode estar presente no app se os métodos dela foram inlined em outras classes. Para garantir que o código foi completamente removido e não apenas inlined, adicione uma regra correspondente que impeça o R8 de realizar otimizações na classe de destino, combinando -checkdiscard com uma regra -keep,allowshrinking. Isso proíbe otimizações como mesclagem e inserção de classes. Se a regra -checkdiscard for aprovada, nenhum dos conteúdos das classes correspondentes estará no app otimizado.

O exemplo a seguir demonstra esse uso:

# Either keep or remove the class, don't rename or otherwise optimize it
-keep,allowshrinking class com.example.foo { *; }

# Verify that the class and all of its fields and methods are removed.
-checkdiscard class com.example.foo

-whyareyoukeeping

Use a regra -whyareyoukeeping para determinar por que o R8 manteve uma classe, um campo ou um método específico no build do app. Um item pode ser mantido por vários motivos, mas essa regra só fornece o que explica o caminho mais curto para o item a partir de um item mantido. Se você remover esse caminho do seu código, o item ainda poderá ser retido, mas por um motivo diferente.

Os possíveis motivos são:

  • Uma regra de manutenção: pode ser do app, de uma biblioteca consumida ou de regras geradas pelo AAPT (Android Asset Packaging Tool).

  • Referências transitivas de código ou recursos mantidos: se o R8 retiver código ou XML (como layouts), tudo o que ele referenciar estaticamente será mantido.

A sintaxe é:


-whyareyoukeeping <class_specification>

Exemplo:

-whyareyoukeeping class com.example.foo.MainActivity {
  private void setLabel(...);
}

A saída é impressa no console.

Se você não tiver nenhuma regra mantendo setLabel(), a saída será:

com.example.foo.MainActivity
|- is referenced in keep rule:
|  /app/build/intermediates/aapt_proguard_file/release/processReleaseResources/aapt_rules.txt:4:1
Nothing is keeping void com.example.foo.MainActivity.setLabel()

Se você tiver uma regra de permanência segmentando setLabel(), a saída será semelhante a esta:

com.example.foo.MainActivity
|- is referenced in keep rule:
| /app/proguard-rules.pro:23:1
void com.example.foo.MainActivity.setLabel()
|- is referenced in keep rule:
|  /app/proguard-rules.pro:23:1