7

I've seen some links for counting the methods on Linux and MacOS, but I haven't seen anything for Windows. How do you count a number of methods in a .dex or .jar file?

Sasa Sekulic
  • 669
  • 4
  • 12

2 Answers2

13

After unsuccessful search for a solution, I wrote two simple batch/shell scripts that do that.

The first one, methodcount.bat, checks if the file is .dex or .jar, and if it's a .jar file, it processes it with dx into dex file and then calls the second one, printhex.ps1, that actually checks the number of methods in the dex file - it reads 2 bytes beginning at 88 (little endian) and converts them into a decimal number.

To use this you to have dx somewhere in your path (it's in the android SDK build-tools/xx.x.x folder) and have PowerShell installed (it should already be installed on Windows 7/8).

Usage is very simple: methodcount.bat filename.dex|filename.jar.

Here are the scripts, but you can also find them on gist: https://gist.github.com/mrsasha/9f24e129ced1b1db791b.

methodcount.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() 
Sasa Sekulic
  • 669
  • 4
  • 12
  • so so so so good , thank you so much, in this way I can check my Android app method – Ashton Sep 30 '14 at 10:09
  • For a batch method count in multiple jars I'd recommend calling `printhex.ps1` without `-noexit` option in a batch cycle like this: `@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 contains a list of jar file names. '\n' means a newline` – IPSUS Apr 02 '15 at 15:53
1

I see this question is old, but there's a Gradle plugin that will work on Windows which will report the method-reference count in an APK on each build: https://github.com/KeepSafe/dexcount-gradle-plugin.

Ben
  • 6,023
  • 1
  • 25
  • 40
  • This Gradle plugin is easy to use, and does report the total method count in the APK. Sadly it does not report the counts in the JAR files that went into that APK. So this effectively answers the DEX half of the OP, but not the JAR half. – Jesse Chisholm Jan 05 '17 at 03:05
  • That's true, but beside the point. It's meaningless to talk about method counts of a jar - with multiple jars as input to dx, method references are merged and sometimes removed during dexing, and so there is no one-to-one mapping between classfile and dex method references. – Ben Jan 04 '18 at 02:15
  • re: `meaningless to talk about method count in jar` a moot point. I mentioned that this solution didn't address JAR files only because the OP asked about JAR files. – Jesse Chisholm Jan 09 '18 at 00:25