web-dev-qa-db-fra.com

Existe-t-il un moyen d'obtenir le nombre de méthodes numériques utilisées dans un fichier jar

Puis-je avoir le nombre de toutes les méthodes utilisées dans un fichier jar. Mon APK utilise certains JARS externes et il y a un certain nombre de classes une centaine pour être précis.

J'ai utilisé des décompilateurs comme dex2jar JAD et d'autres pour n'en nommer que quelques-uns, mais ils semblent tous montrer des méthodes uniquement dans un fichier de classe particulier.

Existe-t-il un moyen d'obtenir un nombre total?

33
freeky9

Vous pouvez convertir le fichier jar en fichier dex, puis extraire le nombre de références de méthode de l'en-tête. Il est stocké sous la forme d'un petit entier endian non signé, à l'offset 88 (0x58).

dx --dex --output=temp.dex orig.jar
cat temp.dex | head -c 92 | tail -c 4 | hexdump -e '1/4 "%d\n"'

Gardez à l'esprit qu'il s'agit du nombre de méthodes uniques référencées et non du nombre de références de méthode. En d'autres termes, si une méthode particulière est référencée deux fois dans le fichier dex, elle ne sera comptée qu'une seule fois dans le décompte de l'en-tête. Et lorsque vous importez ce pot dans votre apk, les références de méthode qui sont communes entre les deux sont dédupliquées, donc le nombre total de références de méthode de l'apk fusionné final sera <= la somme des deux.

81
JesusFreke

Ce plugin gradle https://github.com/KeepSafe/dexcount-gradle-plugin vous montrera le nombre total de méthodes après l'assemblage et génère également un rapport avec le nombre de méthodes de chaque package. Ce qui après avoir été trié ressemble à ceci:

30145    com
27704    org
20950    Android
17140    org.spongycastle
16605    Android.support
9760     com.google
8930     com.fasterxml.jackson
8930     com.fasterxml
8633     Android.support.v4
7020     com.fasterxml.jackson.databind
6426     Android.support.v7
5311     com.google.protobuf
4705     org.spongycastle.crypto
...

En combinaison avec la commande gradle

.\gradlew app:dependencies

qui imprime l'arborescence des dépendances, vous obtiendrez un bon aperçu de la dépendance qui a besoin de combien de méthodes.

11
patrickf

Cyvis peut lire un .jar ou .class fichier et affichera à la fois le nombre total de méthodes plus la complexité cyclomatique et le nombre d'instructions pour chaque méthode. L'interface graphique est un peu ... portable ... mais je l'ai exécutée sur Ubuntu et il dit que cela fonctionne sur Windows. Semble assez bon pour une source d'informations de première coupe sur la probabilité qu'une bibliothèque vous cause des problèmes.

3
Jon Shemitz

Utilisez le http://github.com/mihaip/dex-method-counts pour calculer le nombre de méthodes de partout (JAR, AAR, DEX, APK)

DEX ou APK:

./dex-method-counts <your_file_path>.DEX ou ./dex-method-counts <your_file_path>.APK

JAR

il suffit de faire un DEX à partir de JAR comme indiqué ci-dessus comme ceci:

<your_path_to_Android_buil_tools>/dx --dex --output=temp.dex orig.jar

puis

./dex-method-counts temp.dex

AAR

Décompressez-le d'abord (ouais AAR c'est Zip en fait) puis utilisez classes.jar comme indiqué ci-dessus dans la section JAR

unzip mylib.aar -d mylib

dx --dex --output=temp.dex mylib/classes.jar

dex-method-counts temp.dex

3

Pour les cas où vous avez déjà dépassé la limite de 64 Ko, une autre approche consisterait à utiliser l'option --multi-dex pour dx, puis à utiliser la fonctionnalité "list methods" de baksmali sur tous les fichiers dex générés par dx. Ensuite, vous devez combiner ces listes, trier la liste combinée et supprimer tous les doublons. Le nombre de méthodes qui vous reste sera le nombre total de méthodes.

dx --dex --multi-dex --output=out orig.jar
find out -name classes*.dex -exec baksmali list methods {} \; | sort | uniq | wc -l
1
JesusFreke

Si vous avez le code source (ou pouvez le télécharger), Sonar fera une analyse statique comme celle-ci. Vous pouvez également vérifier un tas d'autres mesures de complexité qui peuvent être utiles pour ce que vous essayez de faire. (Ce serait bien de nous dire ce que vous essayez de faire.;))

0
Barett

Je viens d'écrire un script python pour cela pour obtenir une estimation approximative

import re
import subprocess
import sys

for jarfile in sys.argv[1:]:
    class_output = subprocess.check_output(['jar', 'tf', jarfile])
    classes = [c.replace('/', '.') for c in re.findall(r'(.*)\.class', class_output)]
    methods = []
    if classes:
        def_out = subprocess.check_output(['javap', '-classpath', jarfile] + classes)
        # This is pretty hacky: look for parentheses in the declaration line.
        num_methods = sum(1 for line in def_out if '(' in line)
    else:
        num_methods = 0
    print '{} {} {}'.format(num_methods, len(classes), jarfile)

Je venais de rencontrer la limite de la méthode Android 64K, et mes dépendances n'étaient pas encore indexées par le service methodcount.com.

0
matt

Pour trouver le nombre de méthodes dans la bibliothèque Gradle, vous pouvez utiliser ceci - http://www.methodscount.com

Il fournit également un plugin pour Android studio.

http://www.methodscount.com/plugins

0
Zeero0
  1. Utilisez le programme jar avec le paramètre -x pour extraire les fichiers de votre fichier jar.

  2. Appliquez un décompilateur à chaque fichier .class pour obtenir le nombre de méthodes dans chaque fichier.

  3. Additionnez le nombre de méthodes.

0
Patricia Shanahan

J'ai écrit un script basé sur la réponse de @ JesusFreke pour ce problème et pour un autre problème ( https://stackoverflow.com/a/21485222/6643139 ):

#!/bin/bash
unzip $1 classes.jar -d aarsize &&
  dx --dex --output=aarsize/temp.dex aarsize/classes.jar &&
  hexdump -s 88 -n 4 -e '1/4 "%d\n"' aarsize/temp.dex &&
  rm -rf aarsize

Enregistrez-le sous un nom de fichier "aarsize", chmod +x pour cela, sortie de aarsize your_aar_file:

$ aarsize status-bar-compat-release.aar 
Archive:  status-bar-compat-release.aar
  inflating: aarsize/classes.jar     
91

Le 91 est le nombre de méthodes de votre fichier aar.

0
黄浩杭