在Windows上统计Android JAR/DEX的方法数量

7

我看到一些关于Linux和MacOS上计算方法数量的链接,但是在Windows上没有看到。如何计算.dex或.jar文件中的方法数?

2个回答

13
在找不到解决方案后,我编写了两个简单的批处理/Shell脚本来实现这一功能。
第一个脚本方法methodcount.bat会检查文件是.dex还是.jar文件。如果是.jar文件,则使用dx将其转换为dex文件,然后调用第二个脚本printhex.ps1,该脚本会实际检查dex文件中的方法数量 - 它读取从88开始的2个字节(小端),并将它们转换为十进制数。 使用前需要将dx添加至系统路径(它位于android SDK build-tools/xx.x.x文件夹中)并安装PowerShell(Windows 7/8上应已安装)。 使用非常简单:methodcount.bat filename.dex|filename.jar
以下是脚本,您也可以在gist上找到它们:https://gist.github.com/mrsasha/9f24e129ced1b1db791bmethodcount.bat
@ECHO OFF
IF "%1"=="" GOTO MissingFileNameError
IF EXIST "%1" (GOTO ContinueProcessing) ELSE (GOTO FileDoesntExist)

:ContinueProcessing
set FileNameToProcess=%1
set FileNameForDx=%~n1.dex
IF "%~x1"==".dex" GOTO ProcessWithPowerShell

REM preprocess Jar with dx
IF "%~x1"==".jar" (
    ECHO Processing Jar %FileNameToProcess% with DX!
    CALL dx --dex --output=%FileNameForDx% %FileNameToProcess%
    set FileNameToProcess=%FileNameForDx%
    IF ERRORLEVEL 1 GOTO DxProcessingError
)

:ProcessWithPowerShell
ECHO Counting methods in DEX file %FileNameToProcess%
CALL powershell -noexit -executionpolicy bypass "& ".\printhex.ps1" %FileNameToProcess%
GOTO End

:MissingFileNameError
@ECHO Missing filename for processing
GOTO End

:DxProcessingError
@ECHO Error processing file %1% with dx!
GOTO End

:FileDoesntExist
@ECHO File %1% doesn't exist!
GOTO End

:End

printhex.ps1

<#
.SYNOPSIS
Outputs the number of methods in a dex file.

.PARAMETER Path
Specifies the path to a file. Wildcards are not permitted.

#>
param(
  [parameter(Position=0,Mandatory=$TRUE)]
    [String] $Path
)

if ( -not (test-path -literalpath $Path) ) {
  write-error "Path '$Path' not found." -category ObjectNotFound
  exit
}

$item = get-item -literalpath $Path -force
if ( -not ($? -and ($item -is [System.IO.FileInfo])) ) {
  write-error "'$Path' is not a file in the file system." -category InvalidType
  exit
}

if ( $item.Length -gt [UInt32]::MaxValue ) {
  write-error "'$Path' is too large." -category OpenError
  exit
}

$stream = [System.IO.File]::OpenRead($item.FullName)
$buffer = new-object Byte[] 2
$stream.Position = 88
$bytesread = $stream.Read($buffer, 0, 2)
$output = $buffer[0..1] 
#("{1:X2} {0:X2}") -f $output
$outputdec = $buffer[1]*256 + $buffer[0]
"Number of methods is " + $outputdec
$stream.Close() 

非常好,非常感谢,这样我就可以检查我的Android应用程序方法了。 - Ashton
对于多个JAR包的批量方法计数,我建议在批处理循环中调用printhex.ps1而不使用-noexit选项,如下所示:@echo "START" >mc_res.txt \n @for /F "tokens=*" %%t in (mc.txt) do (\n call methodcount.bat %%t >>mc_res.txt\n )\n@rem mc.txt 包含JAR文件名列表。 '\n' 表示换行符 - IPSUS

1

这个Gradle插件易于使用,并且可以报告APK中的总方法数。不幸的是,它不会报告进入该APK的JAR文件中的计数。因此,这有效地回答了OP的DEX一半,但没有回答JAR一半。 - Jesse Chisholm
没错,但这不是重点。谈论一个jar文件的方法计数是没有意义的 - 在将多个jar文件作为dx的输入时,方法引用会在dexing过程中合并和有时删除,因此类文件和dex方法引用之间不存在一对一的映射关系。 - Ben
关于“在jar中谈论方法计数没有意义”的问题,这是一个无意义的争论。我之所以提到这个解决方案没有涉及JAR文件,仅仅是因为OP问了关于JAR文件的问题。 - Jesse Chisholm

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接