Comment conserver / exclure un chemin de package particulier lors de l'utilisation de proguard?

110

Je souhaite exclure certains chemins de fichiers de ProGuard. Exemplecom.myapp.customcomponents

Comment puis-je faire ceci? Je déteste placer des indicateurs -keep pour chaque fichier de composant personnalisé que j'ai dans ce répertoire.

J'ai essayé ce qui suit mais cela ne fonctionne pas:

-keep public class com.myapp.customcomponents.*
Jona
la source

Réponses:

241

Vous ne spécifiez pas en quoi cela ne fonctionne pas. Votre configuration conserve les noms de toutes les classes publiques dans le package spécifié:

-keep public class com.myapp.customcomponents.*

La configuration suivante conserve les noms de toutes les classes publiques dans le package spécifié et ses sous-packages:

-keep public class com.myapp.customcomponents.**

La configuration suivante conserve les noms de toutes les classes / champs / méthodes publics / protégés dans le package spécifié et ses sous-packages:

-keep public class com.myapp.customcomponents.** {
  public protected *;
}
Eric Lafortune
la source
6
Les doubles astérisques (**) ne se compilent plus (Android Studio 4.0)
Daniel
1
Android Studio 4.x affichera des erreurs telles que "Nom de classe non résolu", etc. pour les doubles astérisques (**), mais cela fonctionnera comme prévu.
Mahmudul Hasan Shohag
Son corrigé et ne donnera pas d'erreurs dans les versions à venir, vérifiez les détails ici
shadygoneinsane
56

Ajoutez la ligne suivante en bas de votre configuration ProGuard:

-keep class com.facebook.** { *; }

Remplacez le nom du package en conséquence, ici le package com.facebooksera exclu de ProGuard.

Pawan Maheshwari
la source
13
pourquoi garder et ne pas avertir utiliser ensemble
Jongz Puangput
@Jongz Puangput, si j'ai raison - si l'application n'utilise pas le package com.facebook, alors lors de la construction, la note "la configuration se réfère à la classe inconnue ..." sera affichée. -dontwarn désactiver cette note.
Yura Shinkarev
14
que veut { *; }dire?
Muhammad Babar
15
@MuhammadBabar i signifie chaque membre, méthode, classe dans chaque portée, bref tout!
Omar El Don
1

Beaucoup de gens semblent recommander -keep class com.myapp.customcomponents.** { *; }comme moyen d'exclure un chemin du traitement. Vois ici:

  1. exclure des packages de proguard
  2. Faire en sorte que Proguard ignore complètement le paquet
  3. Empêcher un répertoire de l'obfuscation de proguard

Le problème avec cette solution est qu'il y a encore un certain niveau d'obscurcissement en cours, ce qui peut casser votre code. Vous pouvez voir le mappage dans l'impression de mappage:

java.lang.String toString() -> toString
int getMemoizedSerializedSize() -> getMemoizedSerializedSize
void setMemoizedSerializedSize(int) -> setMemoizedSerializedSize
int getSerializedSize() -> getSerializedSize
boolean equals(java.lang.Object) -> equals
int hashCode() -> hashCode

La solution que j'ai choisie est un processus en deux étapes. Tout d'abord, utilisez injarsun filtre pour sélectionner le chemin du package que je souhaite traiter. Il est possible d'ajouter les autres chemins de package en tant que bibliothèques.

-injars       artifacts/in.jar(org/toprocess/**.class)
-outjars      out/processed.jar
-libraryjars  artifacts/in.jar(org/skipped/**.class)
-libraryjars  artifacts/in.jar(org/moreskipped/**.class)

Deuxièmement, fusionnez le pot traité avec le pot d'origine, mais uniquement les chemins qui ont été ignorés.

-injars  out/processed.jar
-injars  artifacts/in.jar(org/skipped/**.class)
-injars  artifacts/in.jar(org/moreskipped/**.class)
-outjars out/merged.jar

-dontshrink
-dontoptimize
-dontobfuscate

Le résultat est un fichier jar fusionné qui est la combinaison du chemin du package traité et des chemins ignorés. Cet exercice est invalide, si quelqu'un peut fournir un moyen d'ignorer complètement le traitement de certains chemins (que je n'ai pas trouvé).

PLG
la source
1

Ce qui a fonctionné pour moi avec Android Studio 4.0 est:

-keepclassmembers class com.myapp.customcomponents.* {
    <fields>;
    <init>();
    <methods>;
}

Les doubles astérisques (**) dans les autres réponses ne fonctionnaient pas pour moi. J'ai également essayé la configuration ci-dessus avec R8, fonctionne très bien.

mtsahakis
la source
cette réponse est la réponse la plus à jour que je pense. Merci.
Gogo-the-Cat