Java 有没有一种方法可以获得jar文件中使用的方法的数量
我可以得到一个jar文件中使用的所有方法的计数吗。 我的APK使用某些外部JAR,准确地说,大约有100个类 我使用过dex2jar JAD等反编译器,但它们似乎都只在特定的类文件中显示方法Java 有没有一种方法可以获得jar文件中使用的方法的数量,java,android,dex,Java,Android,Dex,我可以得到一个jar文件中使用的所有方法的计数吗。 我的APK使用某些外部JAR,准确地说,大约有100个类 我使用过dex2jar JAD等反编译器,但它们似乎都只在特定的类文件中显示方法 有什么方法可以得到总数吗?如果你有源代码(或者可以下载),我会在上面做这样的静态分析。您还可以检查一系列其他复杂性度量,这些度量可能对您正在尝试的操作有用。(最好告诉我们你想做什么。) 使用带有-x参数的jar程序 从您的jar文件 对每个.class文件应用反编译器以获取方法的数量 在每个文件中 把方法数
有什么方法可以得到总数吗?如果你有源代码(或者可以下载),我会在上面做这样的静态分析。您还可以检查一系列其他复杂性度量,这些度量可能对您正在尝试的操作有用。(最好告诉我们你想做什么。)
您可以将jar转换为dex文件,然后从标头中提取方法引用的数量。它存储为偏移量88(0x58)处的无符号小端整数
请记住,这是引用的唯一方法的数量,而不是方法引用的数量。换句话说,如果一个特定的方法在dex文件中被引用了两次,那么它在报头的计数中只会被计数一次。当您将此jar导入apk时,这两个jar之间常见的方法引用将被删除,因此最终合并的apk的总方法引用计数将是可以读取
.jar
或.class
文件,并将显示每个方法的总方法计数加上圈复杂度和指令计数。GUI有点。。。便携式。。。但我在Ubuntu上运行过,它说它可以在Windows上运行。对于一个库给您带来麻烦的可能性的第一个信息源来说,这似乎非常好。使用命令行,在解压缩JAR之后,类似这样的东西应该可以工作:
for f in *.class; do javap -c $(basename -s .class $f) | grep invoke | sed 's/.*Method\(.*\)/\1/g'; done | wc -l
此gradle插件将显示组装后的总方法计数,并生成包含每个包的方法计数的报告。排序后的结果如下所示:
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
这将打印出依赖关系树,您将很好地了解哪个依赖关系需要多少方法。使用计算来自任何地方的方法数(JAR、AAR、DEX、APK)
DEX或APK:
/dex方法计数。dex
或
/dex方法计数。APK
罐子
只需从JAR创建一个DEX,如上图所示:
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
...
/dx--dex--output=temp.dex orig.jar
然后
/dex方法计算温度dex
(public|protected|private|static|\s) +[\w\<\>\[\]]+\s+(\w+) *\([^\)]*\) *(\{?|[^;])
AAR
首先解压缩它(是的,实际上是ZIP),然后使用classes.jar,如上面jar部分所示
解压缩mylib.aar-d mylib
dx--dex--output=temp.dex mylib/classes.jar
dex方法计算临时dex
(公共受保护私有静态)
(public|protected|private|static|\s) +[\w\<\>\[\]]+\s+(\w+) *\([^\)]*\) *(\{?|[^;])
使用
CTRL+SHIFT+F
在项目中搜索。它帮助了我我刚刚为此编写了一个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服务还没有为我的依赖项编制索引。我根据@JesusFreke对这个问题和另一个问题的答案()编写了一个脚本: 将其保存到文件名“aarsize”中,
chmod+x
对于它,输出aarsize您的aar\u文件
:
$ aarsize status-bar-compat-release.aar
Archive: status-bar-compat-release.aar
inflating: aarsize/classes.jar
91
91
是aar文件的方法计数。对于已经超过64k方法限制的情况,另一种方法是使用--multi-dex选项选择dx,然后使用baksmali的“列表方法”dx生成的所有dex文件上的功能。接下来,您将组合这些列表,对组合列表进行排序并删除任何重复项。剩下的方法数将是方法总数
dx --dex --multi-dex --output=out orig.jar
find out -name classes*.dex -exec baksmali list methods {} \; | sort | uniq | wc -l
要查找gradle库中的方法计数,可以使用- 它还为android studio提供插件
你想定义数字还是使用数字?@Peter:我可以根据用途使用两个选项-方法声明或方法引用..所以你不是说程序运行时实际使用了多少。以下是我的答案:android sdk macosx/build tools/17.0.0/DX谢谢,基于你的回答,我写了一篇jar文件夹中计数方法的脚本:不需要cat/head/tail:
hextdump-s88-n4-e1/4“%d\n”‘temp.dex
当您组装了一个dex文件时,使用dx是非常好的,但是我遇到了一种情况,当我超过65k限制时,我无法组装dex文件来检查方法计数。问题仍然存在,如何直接从jar获得方法计数而不需要中间数据dex@GenaBatsyan这是一个很好的观点,我的目标是wer是使用大多数开发人员可能已经在他们的机器上使用的工具提供解决方案的(至少,在类似unix的机器上,安装了android sdk)。但是,请看我刚才为您描述的案例添加的替代答案,它使用dx和baksmali。奇怪的是,我显然对此投了反对票(我不记得这样做了,鼠标点击不好?)。如果你编辑帖子,我可以更改我的投票。对不起:(@powerj1984没什么大不了的-我有很多分数。但是我做了一个虚拟编辑,所以你可以整理它。我尝试了这个工具。如果它能对事情进行排序(包是随机排列的),它会很有用,以及是否可以递归地查看包及其子包中类和方法的总数。它不显示整个项目的方法总数,只显示包和类的总数。此工具的其他问题:1)自2006年以来未更新。2)不划分内部类,只划分顶级类。例如,我的外部类有8个方法,但一个内部类可能有50个以上未提及的方法。我猜OP想知道哪个J