2
votes

Instructions de journalisation après le plugin Android Gradle 3.4.0 (avec le compilateur R8)

Le nouveau compilateur R8 d'Android détecte et supprime en toute sécurité les classes, champs, méthodes et attributs inutilisés de votre application et de ses dépendances de bibliothèque, entre autres.

Supprime-t-il également les instructions de journal? Par exemple, si je construis mon APK Release, prêt pour le lancement, puis-je laisser mes instructions de journal dans mon application en toute sécurité?

Log.d("LogStatement", variable.toString())

ou dois-je les supprimer chaque fois que je télécharge / mets à jour mon application sur Google Play?


0 commentaires

3 Réponses :


0
votes

Non, du tout, vous pouvez le faire via Proguard Tools. Dans build.gradle vous pouvez activer Proguard

-assumenosideeffects class android.util.Log {
  public static *** v(...);
  public static *** d(...);
  public static *** i(...);
  public static *** w(...);
  public static *** e(...);
}

Modifiez le fichier proguard-rules.pro, qui devrait se trouver dans le répertoire de votre application Android standard:

release {
        minifyEnabled true

        proguardFiles getDefaultProguardFile(
                'proguard-android-optimize.txt'),
                'proguard-rules.pro'
    }

J'espère que cette réponse vous aidera.


2 commentaires

Merci. Mais je demande si Android le fait automatiquement. Parce que la documentation Android dit maintenant: Lorsque vous créez votre projet à l'aide du plugin Android Gradle 3.4.0 ou supérieur, le plugin n'utilise plus ProGuard pour effectuer l'optimisation du code de compilation. Au lieu de cela, le plugin fonctionne avec le compilateur R8 pour gérer les tâches de compilation suivantes ... developer.android.com/studio/build/shrink-code


Oh d'accord, c'est une information manquante pour moi! Merci.



0
votes

Je ne suis pas sûr, si vous cherchez toujours une réponse à cela, mais qu'elle n'est pas supprimée, si vous inspectez l'apk à l'aide de l'analyseur apk (utilisez le fichier de mappage pour la lisibilité), vous verrez que la classe Log existe. Et comme @Younes Charfaoui l'a mentionné, vous pouvez ajouter ces règles proguard pour le supprimer.


0 commentaires

0
votes

Réponse courte: cela dépend.

Comme vous pouvez le voir dans ce numéro pour R8: https://issuetracker.google.com/issues/73708157

Cela dépend de l'enregistreur que vous utilisez. Et bien sûr, vous devez définir les règles ProGuard appropriées.

Lors de l'utilisation des règles ProGuard telles que mentionnées par Younes Charfaoui , l'appel à l'enregistreur sera supprimé. Cela ne fonctionne que lorsque vous utilisez des chaînes simples:

if (Logger.SHOW_LOG) {
  logger.debug("My log statement will show some variable: " + variable1 + " and maybe another one: " + variable2);
}

-> sera correctement supprimé.

Mais lors de l'utilisation (automatique) de StringBuilder lors de la journalisation:

logger.debug("My log statement will show some variable: {} and maybe another one: {}", variable1, variable2);

seul l'appel à l'enregistreur sera supprimé.
Cela signifie que la partie StringBuilder restera visible dans le ByteCode résultant.
Vous devez faire attention, ne pas utiliser de StringBuilders automatiques.
Un autre exemple:

invoke-virtual {p1}, Landroid/os/Bundle;->toString()Ljava/lang/String;

voir:

@Override
public void onCreate(Bundle savedInstanceState) {
  Log.d("MyFragment::onCreate", "will be removed"); // will be dropped
  Log.d("MyFragment::onCreate::", savedInstanceState.toString()); // call for toString() will remain
}

Il existe des règles ProGuard qui ne sont prises en charge que par ProGuard et pas encore par R8, ce qui supprimerait facilement les StringBuilders restants: assumenoexternalsideeffects, assumenoexternalreturnvalues.

Lorsque vous utilisez la journalisation avec StringBuilder automatique, vous avez:

  • mauvaises performances car le StringBuilder effectue son action et le résultat est inutilisé.
  • a paralysé votre obfuscation, parce que quiconque essaie de démonter votre apk et lit le ByteCode peut comprendre le code obscurci beaucoup plus facilement en raison du StringBuilder restant de vos instructions de journal de débogage.

Pour vraiment vous assurer que votre code de journalisation est supprimé avec R8, vous avez deux options:

  • Utilisez une bibliothèque de journalisation prenant en charge la création de messages (comme slf4j), dans laquelle vous pouvez écrire:
Log.d("LogTag", "My log statement will show some variable: " + variable);
  • Utilisez un test autour de chaque appel à logger (est vraiment moche à lire et augmente la complexité de votre code, juste si vous vous souciez de l'analyse de code statique comme sonarqube).
    Logger.SHOW_LOG doit être un booléen final statique public avec la valeur = false, de sorte que l'optimisation du code détecte la ligne entière comme du code inutilisé et supprime correctement tout ce qui se trouve entre les deux.
Log.d("LogTag", "My log statement");

voir également: http://www.slf4j.org/faq.html#logging_performance

Si vous pensez également que cela devrait fonctionner avec R8 de la même manière qu'avec ProGuard, veuillez marquer l'un des problèmes suivants:
Ajout de la prise en charge de l'option d'optimisation Proguard 6 -assumenoexternalsideeffects
Ajout de la prise en charge de l'option d'optimisation Proguard 6 -assumenoexternalreturnvalues
Améliorez l'élimination de StringBuilder inutilisé


0 commentaires