Best Practices befolgen

Bei der Arbeit mit Keep-Regeln ist es wichtig, die richtige Spezifität zu erreichen, damit Sie von den Vorteilen profitieren und gleichzeitig das Verhalten Ihrer App beibehalten. In den folgenden Abschnitten erfahren Sie mehr über gute Muster und Dinge, die Sie in Keep-Regeln vermeiden sollten.

Gute Muster in Keep-Regeln

Gut definierte Keep-Regeln sind so spezifisch wie möglich und folgen den folgenden Mustern:

  • Geben Sie für die Klassenspezifikation nach Möglichkeit immer eine bestimmte Klasse, eine Basisklasse oder eine mit Anmerkungen versehene Klasse an, wie in den folgenden Beispielen gezeigt:

    -keepclassmembers class com.example.MyClass {
      void someSpecificMethod();
    }
    
    -keepclassmembers ** extends com.example.MyBaseClass {
      void someSpecificMethod();
    }
    
    -keepclassmembers @com.example.MyAnnotation class ** {
      void someSpecificMethod();
    }
    
  • Verwenden Sie nach Möglichkeit Anmerkungen in Ihrem Quellcode und richten Sie diese Anmerkungen dann direkt in Ihren Keep-Regeln aus. Dadurch wird eine klare, explizite Verbindung zwischen Ihrem Code und den Regeln hergestellt, die ihn beibehalten. So wird Ihre Konfiguration robuster, leichter verständlich und weniger anfällig für Fehler bei Codeänderungen.

    Das folgende Snippet zeigt beispielsweise, wie Sie die Klasse „MyClass“ sowie andere Klassen beibehalten können, die mit „@com.example.DisplayComponent“ annotiert sind:

    // In the source code
    @com.example.DisplayComponent
    class MyClass { /* ... */ }
    
    // In the keep rules
    -keep @com.example.DisplayComponent class * {*;}
    

    Wir empfehlen, Ihre Anmerkungen so zu benennen, dass sie einen aussagekräftigen Kontext dafür liefern, warum Codeabschnitte beibehalten werden. Verwenden Sie beispielsweise „@DisplayComponent“ für eine App, bei der für Anzeigekomponenten einige Teile beibehalten werden müssen.

  • Nach Möglichkeit sollte die Mitgliedsspezifikation deklariert werden und nur auf die Teile der Klasse verweisen, die für die Funktion der App beibehalten werden müssen. Es wird empfohlen, eine Regel nicht auf eine gesamte Klasse anzuwenden, indem Sie den optionalen Mitgliedsbereich als { *; } definieren, es sei denn, dies ist unbedingt erforderlich.

    -keepclassmembers com.example.MyClass {
      void someSpecificMethod();
      void @com.example.MyAnnotation *;
    }
    
  • Wenn Sie die repackageclasses globale Option verwenden, geben Sie den optionalen Paketnamen nicht an. Dadurch werden kleinere DEX-Dateien erstellt, da das Paketpräfix in den neu verpackten Klassennamen weggelassen wird.

  • Behalten Sie Keep-Regeln für alle Elemente bei, auf die per Reflektion zugegriffen wird. Auch wenn solche Elemente von R8 ohne explizite Keep-Regeln beibehalten werden, ist es wichtig, die tatsächlichen Regeln beizubehalten, da zukünftige Codeänderungen dazu führen könnten, dass R8 diese Elemente nicht mehr beibehält.

    Für die Reflektion in Ihrem eigenen Code können Sie Jetpack Keep verwenden, um Keep-Regeln zu generieren, die einfacher zu verwalten sind. Jede Anmerkung befindet sich im Code, der die Reflektion ausführt. Wenn Sie diesen Code ändern, aktualisieren oder entfernen Sie die Anmerkung an derselben Stelle. So werden durch die Regeln keine Codeabschnitte beibehalten, die Ihre App nicht mehr reflektiert. Lint kennzeichnet auch reflektierende Aufrufe, die nicht mit Anmerkungen versehen sind.

  • Verwenden Sie nach Möglichkeit -assumenosideeffects oder -convertchecknotnull, um Null-Prüfungen zu optimieren, da dies die Größe der DEX-Datei Ihrer App erheblich reduzieren kann. Weitere Informationen finden Sie unter Zusätzliche Regeltypen.

Wenn Sie diese Richtlinien nicht einhalten können, können Sie den Code, der beibehalten werden muss, vorübergehend in einem separaten Paket isolieren und Ihre Keep-Regel auf das Paket anwenden. Dies ist jedoch keine langfristige Lösung. Weitere Informationen finden Sie unter Optimierungen schrittweise einführen. Wenn Sie eine Keep-Regel für ein Paket verwenden möchten, definieren Sie eine Keep-Regel wie im folgenden Beispiel:

-keepclassmembers class com.example.pkg.** { *; }

Besser vermeiden

Die Syntax für Keep-Regeln bietet viele Optionen. Für messbare, nachhaltige Leistungsverbesserungen empfehlen wir jedoch, Folgendes nicht zu verwenden:

  • Verwenden Sie keine paketweiten Keep-Regeln wie -keep class com.example.pkg.** { *; } langfristig. Sie können vorübergehend verwendet werden, um Probleme bei der Konfiguration von R8 zu umgehen. Weitere Informationen finden Sie unter Optimierungsumfang begrenzen. Seien Sie generell vorsichtig mit Platzhaltern und stellen Sie sicher, dass Sie nur den Code beibehalten, den Sie benötigen.
  • Vermeiden Sie nach Möglichkeit Bibliotheken, bei denen Sie Keep-Regeln kopieren und einfügen müssen, insbesondere paketweite Keep-Regeln. Bibliotheken, die auf Android gut funktionieren sollen, sollten Reflektion nach Möglichkeit vermeiden und bei Bedarf Keep-Regeln für Nutzer einbetten.
  • Vermeiden Sie den Inversionsoperator ! in Keep-Regeln, da Sie eine Regel sonst versehentlich auf fast jede Klasse in Ihrer Anwendung anwenden könnten.

Wenn Sie diese Regeln nicht einhalten können, verwenden Sie möglicherweise viel offene Reflektion. Vermeiden Sie entweder die Reflektion oder die Bibliothek, die Reflektion verwendet (siehe die Fallstudie zu Gson).