Есть ли способ получить количество меток чисел, используемых в файле 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. Это помогло мне