Есть ли способ получить количество меток чисел, используемых в файле jar
Можно ли подсчитать все методы, используемые в файле jar.
Мой APK использует определенные внешние JARS, и есть несколько классов вокруг сотни, чтобы быть точным.
Я использовал декомпиляторы, такие как dex2jar JAD и другие, чтобы назвать несколько, но все они, кажется, показывают методы только в определенном файле класса.
Есть ли способ получить общий счет?
Ответы
Ответ 1
Вы можете преобразовать банку в файл dex, а затем вывести количество ссылок на методы из заголовка. Он сохраняется как беззнаковое малое число endian, со смещением 88 (0x58).
dx --dex --output=temp.dex orig.jar
cat temp.dex | head -c 92 | tail -c 4 | hexdump -e '1/4 "%d\n"'
Имейте в виду, что это количество уникальных методов, на которые ссылается, а не количество ссылок на методы. Другими словами, если конкретный метод ссылается дважды в файл dex, он будет подсчитываться только один раз в счетчике в заголовке. И когда вы импортируете эту банку в свой apk, ссылки на методы, которые являются общими между двумя, дедуплицируются, поэтому общий счетчик ссылок метода окончательного объединенного apk будет <= сумма двух.
Ответ 2
Этот gradle плагин https://github.com/KeepSafe/dexcount-gradle-plugin покажет вам итоговый счет метода после сборки, а также создаст отчет с подсчетом метода каждого пакет. Которая после сортировки выглядит так:
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
...
В сочетании с командой gradle
.\gradlew app:dependencies
который печатает дерево зависимостей, вы получите хороший обзор того, какая зависимость требует, сколько методов.
Ответ 3
Cyvis может читать файл .jar
или .class
, и будет отображаться как общий счет метода плюс циклическая сложность, так и количество команд для каждого метода. GUI немного... портативный... но я запустил его на Ubuntu, и он говорит, что он работает в Windows. Кажется, очень хорошо для первоклассного источника информации о том, насколько вероятно, что библиотека даст вам проблемы.
Ответ 4
Используйте http://github.com/mihaip/dex-method-counts для вычисления количества методов извне (JAR, AAR, DEX, APK)
DEX или APK:
./dex-method-counts <your_file_path>.DEX
или
./dex-method-counts <your_file_path>.APK
JAR
просто сделайте DEX из JAR, как было показано выше:
<your_path_to_android_buil_tools>/dx --dex --output=temp.dex orig.jar
а затем
./dex-method-counts temp.dex
AAR
Сначала разархивируйте его (да, AAR это ZIP на самом деле), а затем используйте classes.jar, как показано выше в разделе JAR
unzip mylib.aar -d mylib
dx --dex --output=temp.dex mylib/classes.jar
dex-method-counts temp.dex
Ответ 5
В тех случаях, когда вы уже превысили ограничение 64k-метода, альтернативным подходом было бы использовать параметр -multi-dex для dx, а затем использовать функции "list methods" baksmali для всех файлов dex, которые dx генерирует. Затем вы комбинируете эти списки, сортируете объединенный список и удаляете любые дубликаты. Количество методов, с которыми вы остались, будет общим количеством методов.
dx --dex --multi-dex --output=out orig.jar
find out -name classes*.dex -exec baksmali list methods {} \; | sort | uniq | wc -l
Ответ 6
Если у вас есть исходный код (или вы можете скачать его), Sonar будет делать статический анализ, как на нем. Вы также можете проверить множество других показателей сложности, которые могут быть полезны для того, что вы пытаетесь сделать. (Можете с удовольствием сказать нам, что вы пытаетесь сделать.))
Ответ 7
-
Используйте программу jar с параметром -x для извлечь файлы
из вашего файла jar.
-
Примените декомпилятор к каждому .class файлу, чтобы получить количество методов в каждом файле.
-
Добавьте количество меток.
Ответ 8
Я просто написал python script, чтобы получить приблизительную оценку
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)
Я только что столкнулся с лимитом метода Android 64K, и мои зависимости не были проиндексированы службой methodcount.com.
Ответ 9
Я написал script на основе ответа @JesusFreke для этой проблемы и для другой проблемы (fooobar.com/questions/20797/...):
#!/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
Сохраните его для имени файла "aarsize", chmod +x
для него, вывод aarsize your_aar_file
:
$ aarsize status-bar-compat-release.aar
Archive: status-bar-compat-release.aar
inflating: aarsize/classes.jar
91
91
- это количество методов вашего файла aar.
Ответ 10
С командной строкой, после распаковки JAR, что-то вроде этого должно работать:
for f in *.class; do javap -c $(basename -s .class $f) | grep invoke | sed 's/.*Method\(.*\)/\1/g'; done | wc -l
Ответ 11
(public|protected|private|static|\s) +[\w\<\>\[\]]+\s+(\w+) *\([^\)]*\) *(\{?|[^;])
Искать в проекте с помощью CTRL+SHIFT+F
. Это помогло мне