Utilizzare le regole per risolvere i problemi di ottimizzazione

Oltre alle regole di conservazione generali, ai tipi di regole di conservazione aggiuntive e alle opzioni globali, puoi utilizzare determinate regole per risolvere i problemi di ottimizzazione.

-checkdiscard

La regola -checkdiscard ti consente di verificare se R8 ha eliminato correttamente una classe o un suo membro che prevedevi di rimuovere. Se la classe o il membro specificato non viene eliminato, la build non riesce.

La sintassi per -checkdiscard è la seguente:


-checkdiscard <class_specification>

Nell'esempio seguente, la build non riesce se viene mantenuto il campo userId o il metodo setLabel() della classe com.example.models.User:

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

Il codice della classe potrebbe essere ancora presente nell'app se i relativi metodi sono stati incorporati in altre classi. Per assicurarti che il codice sia stato rimosso completamente e non solo incorporato, aggiungi una regola corrispondente che impedisca a R8 di eseguire ottimizzazioni sulla classe di destinazione, combinando -checkdiscard con una regola -keep,allowshrinking. Ciò vieta ottimizzazioni come l'unione e l'incorporamento delle classi. Se la regola -checkdiscard viene superata, nessuno dei contenuti delle classi corrispondenti si trova nell'app ottimizzata.

Il seguente esempio mostra questo utilizzo:

# 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

Utilizza la regola -whyareyoukeeping per determinare perché R8 ha mantenuto una classe, un campo o un metodo specifico nella build della tua app. Un elemento può essere conservato per più motivi; tuttavia, questa regola fornisce solo quello che spiega il percorso più breve per l'elemento da un elemento conservato. Se rimuovi questo percorso dal codice, potresti comunque vedere l'elemento conservato, ma per un altro motivo.

I possibili motivi sono:

  • Una regola di conservazione: la regola di conservazione può provenire dall'app, da una libreria utilizzata o da regole generate da AAPT (Android Asset Packaging Tool).

  • Riferimenti transitivi da codice o risorse mantenuti: se il codice o l'XML (ad esempio i layout) vengono mantenuti da R8, tutto ciò a cui fanno riferimento staticamente viene mantenuto.

La sintassi è:


-whyareyoukeeping <class_specification>

Ad esempio:

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

L'output viene stampato sulla console.

Se non hai regole che mantengono setLabel(), l'output è:

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 hai una regola di conservazione che ha come target setLabel(), l'output è simile al seguente:

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