2014-09-14 11 views

risposta

13

Dopo una ricerca non riuscita di una soluzione, ho scritto due semplici script batch/shell che lo fanno.

Il primo, methodcount.bat, controlla se il file è .dex o .jar, e se si tratta di un file .jar, elabora con dx in file di dex e quindi chiama il secondo, printhex.ps1, che in realtà controlla il numero di metodi nel file dex - legge 2 byte a partire da 88 (little endian) e li converte in un numero decimale.

Per utilizzare questo comando per avere dx da qualche parte nel percorso (è nella cartella di sviluppo di SDK di Android-tools/xx.x.x) e avere PowerShell installato (dovrebbe essere già installato su Windows 7/8).

uso è molto semplice: methodcount.bat filename.dex | filename.jar.

Ecco gli script, ma è anche possibile trovarli in sintesi: 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() 
+0

così così così bene, grazie mille, in questo modo posso controllare il mio metodo di app Android – Devon

+0

Per un conteggio di metodo batch in più giare mi consiglia di chiamare 'printhex.ps1' senza l'opzione' -noexit' in un ciclo batch come questo: '@echo" START "> mc_res.txt \ n @for/F" token = * "%% t in (mc.txt) do (\ n \t call methodcount.bat %% t >> mc_res.txt \ n ) \ n @ rem mc.txt contiene un elenco di nomi di file jar. '\ n' significa una nuova riga ' – IPSUS

1

Vedo questa domanda è vecchia, ma c'è un plugin Gradle che funziona su Windows, che riporterà il metodo -ferenza conta in un APK su ogni build: https://github.com/KeepSafe/dexcount-gradle-plugin.

+0

Questo plugin Gradle è facile da usare e riporta il conteggio del metodo totale nell'APK. Purtroppo non riporta i conteggi nei file JAR inseriti in quell'APK. Quindi questo in effetti risponde alla metà DEX dell'OP, ma non alla metà del JAR. –

+0

Questo è vero, ma oltre il punto. Non ha senso parlare dei conteggi dei metodi di un jar: con più jar come input per dx, i riferimenti al metodo vengono uniti e talvolta rimossi durante il dexing e quindi non esiste un mapping uno a uno tra i riferimenti del metodo classfile e dex. – Ben

+0

re: "inutile parlare del conteggio dei metodi in jar" un punto controverso. Ho detto che questa soluzione non riguardava i file JAR solo perché l'OP chiedeva informazioni sui file JAR. –

Problemi correlati