33

我可以计算 jar 文件中使用的所有方法的数量吗?我的 APK 使用某些外部 JARS,确切地说,有大约数百个类。

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

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

4

12 回答 12

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文件中被引用了两次,那么它只会在header中的count中被计入一次。而且当你把这个jar导入你的apk时,两者共有的方法引用会被去重,所以最终合并的apk的总方法引用计数将是<=两者之和。

于 2012-12-24T22:35:36.217 回答
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

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

于 2015-09-01T09:43:08.013 回答
3

Cyvis可以读取一个.jar.class文件,并将显示每个方法的总方法数加上圈复杂度和指令数。GUI 有点......便携......但我已经在 Ubuntu 上运行它,它说它可以在 Windows 上运行。对于有关图书馆给您带来麻烦的可能性的初步信息来源来说,这似乎相当不错。

于 2013-03-06T02:12:20.380 回答
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 制作一个 DEX,如上所示:

<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

于 2016-03-10T12:16:07.027 回答
1

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

dx --dex --multi-dex --output=out orig.jar
find out -name classes*.dex -exec baksmali list methods {} \; | sort | uniq | wc -l
于 2017-07-27T21:20:29.370 回答
0

如果你有源代码(或者可以下载),Sonar会在上面做这样的静态分析。您还可以检查许多其他复杂性指标,这些指标可能对您尝试做的事情有用。(可能很高兴告诉我们您要做什么。;))

于 2012-12-24T17:11:58.657 回答
0
  1. 使用带有 -x 参数的 jar 程序 从 jar 文件中提取文件。

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

  3. 将方法计数相加。

于 2012-12-24T17:55:01.610 回答
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 服务索引。

于 2016-08-16T22:12:34.773 回答
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 文件的方法计数。

于 2017-02-14T01:33:45.080 回答
0

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

它还为 android studio 提供插件。

http://www.methodscount.com/plugins

于 2018-01-07T07:48:19.780 回答
-1

使用命令行,在解压缩 JAR 后,应该可以这样:

for f in *.class; do javap -c $(basename -s .class $f) | grep invoke | sed 's/.*Method\(.*\)/\1/g'; done | wc -l
于 2013-05-31T19:53:53.140 回答
-2
(public|protected|private|static|\s) +[\w\<\>\[\]]+\s+(\w+) *\([^\)]*\) *(\{?|[^;])

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

于 2016-05-10T10:02:08.670 回答