AS: 3.5.3; Plugin Android Gradle: 3.5.0; Gradle: 5.6.2;
Nous avons observé une augmentation drastique du nombre de méthodes référencées dans notre application après avoir divisé le module «app» en plusieurs petits modules. Mais ce qui est étrange, c'est que l'ajout de méthodes référencées par chaque classe est inférieur au total mentionné dans Android Apk Analyzer Tool.
À des fins de test, j'ai déplacé WebActivity.class du module «app» au module «adaptateurs» et le nombre de méthodes référencées a été augmenté de 181 méthodes.
Résumer:
app / WebActivity = 63546 Méthodes référencées réelles mais affichant 65394 méthodes. adapter / WebActivity = 63543 Méthodes référencées réelles mais affichant 65575 méthodes.
Nous avons observé que le «nombre de méthodes référencées» a augmenté de près de 10 000 après l'ajout / la division de 4 nouveaux modules.
Quel est le problème exact?
Comment la modularisation des applications peut-elle augmenter considérablement le nombre de méthodes référencées?
Voici les captures d'écran que j'ai prises de deux différences différentes pour les fichiers APK uniquement: WebActivity est passé du module `` application '' au module `` adaptateur '' et 181 méthodes référencées ont été augmentées:
WebActivity dans le module 'app'
WebActivity déplacé vers le module «adaptateur»
Dans les captures d'écran, pourquoi l'ajout de méthodes référencées par chaque classe (marquées en rouge) n'est pas égal au total donné dans Apk Analyzer?
la source
Réponses:
Je lis depuis longtemps sur les performances du code et les paramètres de réglage.En effet, les programmes Android sont l'un de mes centres d'intérêt.
Introduisons d'abord les concepts de base ou les plus importants dans lesquels nous aider à trouver une solution.
Comme l' a déclaré le développeur Android
Par conséquent, les modules ont leurs propres Gradle et dépendances . Et vous pouvez les explorer dans le projet
Hierarchy Viewer
.En fait, la modularisation met l'accent sur les questions de maintenance . Contrairement aux performances, la modularisation a cet impact important:
Voici un diagramme que j'ai tracé pour le rendre clair. Comme vous pouvez le voir en utilisant un module discret, afin d'appeler la méthode A, il est
2N micro secs
comparé àN micro secs
sans module discret.Cette question me vient à l'esprit que les méthodes référencées comptent ce qui est lié à la profondeur de l'héritage?
La réponse est: bien que l'utilisation de la modularisation augmente les méthodes référencées, mais cela n'affecte pas réellement les performances de l'application et le principal problème possible est la profondeur d'héritage dans laquelle, dans la plupart des cas, elle est ignorable .
Je souligne que l'augmentation des méthodes référencées dans la modularisation est due à chaque module Gradle & Dependencies
Conditions dans lesquelles l'impact APK analyseur est important Méthodes référencées
En plus de la déclaration officielle ci-dessus, je veux ajouter une autre condition dans laquelle l'impact APK analyseur qui est:
Quelle est l'expérience du développeur en modularisation?
la modularisation est comme une maison où l' architecture (développeur) définit où devrait être la cuisine et où devraient être les toilettes et où devraient être les toilettes. Et si l'architecture décidait de combiner WC et cuisine? Oui, c'est un désastre.
Cela peut se produire lors de la modularisation si le développeur n'est pas très expérimenté.
Répondre aux questions OP en plus d'informations supplémentaires
Ici, je réponds aux questions posées dans les commentaires
Parce que les modules peuvent être construits, testés et débogués, ils DOIVENT avoir leurs propres Gradle et dépendances.
Pendant que le projet multi-module est en cours d'exécution, le compilateur génère plusieurs
.dex
fichiers, notamment:.dex
fichier pour les dépendances totalement intégrées.dex
s.dex
fichier de dépendances est une intégration de tous les modules gradlesVoyons comment un gradle de module impacte le nombre final de mothods référencés?!
il y a 2
APK
s avec le même résultat mais une différence dans le nombre de méthodes référencées.Ce sont deux activités vides qui ont une
1.7k
différence dans le nombre de méthodes référencées qui est très élevée en fonction de leur fonctionnalité. Leur différence clé est sur le Gradle de leur module, l' un d'eux a été configuré pourUn autre configuré pour
Bien que ce ne soient que des activités vides, une différence minimale dans Gradle a provoqué une
1.7k
différence dans le nombre de méthodes référencées.Et App Gradle est
Ce n'est rien d'autre que le filtre IDE. à coup sûr, si vous sélectionnez uniquement un
.dex
fichier, le nombre de méthodes de référence est égal à la somme des nombres de méthodes référencées de chaque ligne, mais si vous sélectionnez plusieurs.dex
fichiers, vous verrez une différence dans la somme et le nombre réel qu'en raison de l'égalité dans les références qu'Analyzer a préféré les filtrer.dans vos captures d'écran, vous avez sélectionné plusieurs
.dex
fichiers, puis l'égalité du filtre Analyzer.Théoriquement, cela ne devrait PAS augmenter le nombre de méthodes référencées. MAIS , comme je l'ai expliqué, l' expérience développeur a un impact important sur le résultat final.
Team Analyzer doit vérifier et résoudre les problèmes de performances avant la sortie, comme
Maintenant, je veux clarifier comment l' expérience développeur et la maintenance du code affectent le résultat final. MÊME si votre APK utilise des dépendances centralisées
dans l'exemple ci-dessus, j'ai augmenté le nombre
5.1k
de méthodes référencées MÊME SI j'avais des dépendances centralisées !!!!!Comment c'est possible ?
La réponse est: je viens d'ajouter un
.jar
fichier inutile et caché dans lelibs
répertoire du projet. aussi simple que vous pouvez le voir, j'ai affecté le résultat final.Comme vous pouvez le voir Expérience Developer affecte result.as finale par conséquent, pratiquement il est possible que les méthodes référencées compte pour augmenter Bien que théoriquement devrait -elle pas .
la compilation n'a aucun rapport avec les méthodes référencées count.it est conforme à ce que le développeur veut se conformer.
Conclusion
J'ai couvert toutes les possibilités autour de la question. En effet, il peut être issu de différentes situations et un développeur en utilisant cette directive peut résoudre le problème.
NOTE IMPORTANTE: presque toutes les déclarations sont mes enquêtes et recherches. en effet, il peut y avoir des erreurs et des défauts et sera mis à jour afin d'ajouter beaucoup plus d'informations à l'avenir.
la source
Répondre à ma propre question alors que la solution vient juste de cliquer dans mon esprit, bien que cela ne soit pas essayé mais fonctionnerait, certainement ou très probablement. :) La réponse donnée par M.AF a été très utile pour parvenir à une solution finale. Il parle de pourquoi? mais pas comment l'éviter ou comment l'améliorer.
Voici un moyen de récupérer le nombre de méthodes référencées d'origine / réelles -
Cela ne dépend pas de la façon dont nous modularisons l'application, mais de la façon dont nous ajoutons des dépendances. Si nous ajoutons une dépendance en utilisant « implémentation », cette dépendance reste privée au module et aucun autre module ne peut l'utiliser. Et si nous ajoutons la même dépendance en utilisant ' api ' (égal à 'compiler' obsolète) alors elle devient publique et d'autres modules dépendants peuvent l'utiliser. Étant donné que nous utilisons «implémentation» pour ajouter des dépendances dans chaque module dans un projet multi-module, chaque module a toutes les dépendances requises comme autonomes, c'est la raison pour laquelle il peut être compilé individuellement. Cela entraîne une diminution du temps de compilation / compilation car seuls les modules modifiés peuvent être compilés. Mais, l'utilisation de «mise en œuvre» augmente le nombre de méthodes référencées car il y a tellement de méthodes référencées en double.
Donc, si le temps de construction n'est pas votre problème mais que le nombre de méthodes référencées l'est, vous pouvez dessiner l'arborescence des dépendances de tous les modules et éviter d'ajouter des dépendances en double en utilisant 'api' dans le module de base. De cette façon, même le module supérieur peut utiliser les dépendances ajoutées par le module de base, ce qui évitera les doublons. N'oubliez pas que cela augmenterait le temps de construction.
Nous pouvons atteindre les deux si nous pouvions distinguer les dépendances pour le débogage et la version . Ajoutez toutes les dépendances à l'aide de «mise en œuvre» pour la génération de débogage et ajoutez uniquement les dépendances requises et optimisées pour la génération de versions à l'aide de «api» . De cette façon, la génération de débogage sera plus rapide et la version de publication sera plus lente, ce qui est abordable.
Remarque: je mettrais à jour cette réponse une fois que j'aurais compris comment fournir des dépendances distinctes pour le débogage et la version finale.
la source
Je vois toute la différence dans votre forfait «com». Vous pouvez développer et comparer les classes exactes qui ont été réduites. Si vous construisez avec la dernière R8, il peut supprimer du code par défaut. Lorsque vous placez certaines classes dans un module de réduction, je ne sais pas si les classes / méthodes publiques peuvent être supprimées ou doivent rester pour être utilisées dans un autre module.
la source