有没有办法计算jar文件中使用的数字方法的数量

时间:2012-12-24 15:57:40

标签: java android dex

我可以计算jar文件中使用的所有方法吗? 我的APK使用某些外部JARS,并且有大约100个类是准确的。

我使用dex2jar JAD等反编译器等等,但它们似乎只在特定的类文件中显示方法。

有没有办法可以获得总数?

12 个答案:

答案 0 :(得分:81)

您可以将jar转换为dex文件,然后从标题中提取方法引用的数量。它存储为无符号小端整数,偏移量为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文件中引用了两次特定方法,则它只会在标头中的计数中计数一次。当你将这个jar导入你的apk时,两者之间常见的方法引用都是重复数据删除的,所以最终合并的apk的总方法引用数将是< =两者的总和。

答案 1 :(得分:11)

此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

打印出依赖关系树,您将很好地了解哪个依赖关系需要多少方法。

答案 2 :(得分:3)

Cyvis可以读取.jar.class文件,并会显示每个方法的总方法计数加上圈复杂度和指令计数。 GUI有点......便携......但是我在Ubuntu上运行它,它说它适用于Windows。对于图书馆有多大可能给您带来麻烦的第一手信息来说,这似乎非常有用。

答案 3 :(得分:3)

使用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

只需从JAR制作一个DEX,因为它如上所示:

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

然后

./dex-method-counts temp.dex

AAR

首先解压缩它(是的AAR实际上是ZIP),然后使用如上面JAR部分所示的classes.jar

unzip mylib.aar -d mylib

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

dex-method-counts temp.dex

答案 4 :(得分:1)

对于你已经超过64k方法限制的情况,另一种方法是使用-multi-dex选项到dx,然后使用baksmali&#34;列表方法&# 34; dx生成的所有dex文件的功能。接下来,您将组合这些列表,对组合列表进行排序并删除所有重复项。您剩下的方法数量将是方法总数。

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

答案 5 :(得分:0)

如果您有源代码(或可以下载),Sonar将对此进行静态分析。您还可以查看一系列其他复杂度指标,这些指标可能对您尝试执行的操作很有用。 (可能很高兴告诉我们你要做什么。;))

答案 6 :(得分:0)

  1. 将带有-x参数的jar程序用于extract the files 从你的jar文件。

  2. 将反编译器应用于每个.class文件以获取方法数     在每个文件中。

  3. 添加方法计数。

答案 7 :(得分:0)

我刚为此编写了一个python脚本来进行粗略估计

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服务编入索引。

答案 8 :(得分:0)

我根据@ JesusFreke对此问题的回答和另一个问题(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

将其保存为文件名“aarsize”,chmod +xaarsize your_aar_file的输出:

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

91是您的aar文件的方法计数。

答案 9 :(得分:0)

要在gradle库中查找方法计数,您可以使用此方法 -  http://www.methodscount.com

它还为android studio提供了插件。

http://www.methodscount.com/plugins

答案 10 :(得分:-1)

使用命令行,在解压缩JAR之后,这样的事情应该起作用:

for f in *.class; do javap -c $(basename -s .class $f) | grep invoke | sed 's/.*Method\(.*\)/\1/g'; done | wc -l

答案 11 :(得分:-2)

(public|protected|private|static|\s) +[\w\<\>\[\]]+\s+(\w+) *\([^\)]*\) *(\{?|[^;])

使用CTRL+SHIFT+F在项目中搜索。它帮助了我