web-dev-qa-db-ja.com

jarファイルで使用されているnumberメソッドのカウントを取得する方法はありますか

Jarファイルで使用されるすべてのメソッドの数を取得できますか?私のAPKは特定の外部JARを使用し、正確には約100のクラスがあります。

Dex2jar JADなどの逆コンパイラを使用していくつか例を挙げましたが、それらはすべて特定のクラスファイルでのみメソッドを表示するようです。

合計数を取得する方法はありますか?

33
freeky9

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ファイルで2回参照される場合、ヘッダーのカウントでは1回しかカウントされません。また、このjarをapkにインポートすると、2つの間で共通のメソッド参照が重複排除されるため、最終的にマージされたapkのメソッド参照カウントの合計は、2つの合計<=になります。

81
JesusFreke

この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

依存関係ツリーを出力すると、どの依存関係がメソッドをいくつ必要としているかの概要がわかります。

11
patrickf

Cyvis.jarまたは.classファイルを読み取ることができ、合計メソッド数と各メソッドの循環的複雑度および命令数の両方を表示します。 GUIは少し...ポータブルです...しかし、私はUbuntuでそれを実行しました、そして、それはそれがWindowsで動くと言います。ライブラリが問題を引き起こす可能性に関する情報の最初の情報源としては、かなり良いようです。

3
Jon Shemitz

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

3

すでに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
1
JesusFreke

ソースコードがある場合(またはダウンロードできる場合)、 Sonar はこのような静的分析を行います。あなたがやろうとしていることに役立つかもしれない他の複雑さの指標の束をチェックすることもできます。 (あなたがやろうとしていることを教えてくれるといいかもしれません。;))

0
Barett

大まかな見積もりを得るために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サービスによってまだインデックス化されていませんでした。

0
matt

Gradleライブラリでメソッドカウントを見つけるには、これを使用できます- http://www.methodscount.com

また、Android studio。

http://www.methodscount.com/plugins

0
Zeero0
  1. -xパラメータを指定してjarプログラムを使用し、jarファイルから ファイルを抽出 にします。

  2. 各.classファイルに逆コンパイラを適用して、各ファイルのメソッドの数を取得します。

  3. メソッドカウントを合計します。

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ファイルのメソッドカウントです。

0
黄浩杭