我可以计算jar文件中使用的所有方法吗? 我的APK使用某些外部JARS,并且有大约100个类是准确的。
我使用dex2jar JAD等反编译器等等,但它们似乎只在特定的类文件中显示方法。
有没有办法可以获得总数?
答案 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-method-counts <your_file_path>.DEX
要么
./dex-method-counts <your_file_path>.APK
只需从JAR制作一个DEX,因为它如上所示:
<your_path_to_android_buil_tools>/dx --dex --output=temp.dex orig.jar
然后
./dex-method-counts temp.dex
首先解压缩它(是的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)
将带有-x参数的jar程序用于extract the files 从你的jar文件。
将反编译器应用于每个.class文件以获取方法数 在每个文件中。
添加方法计数。
答案 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 +x
,aarsize 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提供了插件。
答案 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
在项目中搜索。它帮助了我