Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android jar/dex method count on windows

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?

like image 899
Sasa Sekulic Avatar asked Sep 14 '14 16:09

Sasa Sekulic


2 Answers

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() 
like image 129
Sasa Sekulic Avatar answered Nov 09 '22 06:11

Sasa Sekulic


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.

like image 30
Ben Avatar answered Nov 09 '22 05:11

Ben