美文网首页技术DevToolsAndroid开发
android检测apk及dex方法数

android检测apk及dex方法数

作者: dongjunkun | 来源:发表于2015-11-16 17:56 被阅读11347次

    随着项目越来越大,android应用不得不面对64k方法数限制的问题,说真的,这个问题很头疼,虽然网上已经有了多种解决方案,multidex,dynamicApk,代码混淆,业务逻辑用c实现然后用jni调用等等,dynamicApk需要工程模块化,高度解耦,修改量极大;代码混淆,已经做了,治标不治本;业务逻辑用c实现然后用jni调用,技术不到家是一种,各种依赖包的添加才是方法数爆棚的罪魁祸首,作用不大;multidex,虽然解了燃眉之急,但仍感到忧心忡忡,不是长久之计,还有各种坑等着你跳。

    问题预防,检测方法数

    虽然目前还没有一劳永逸的方案,只能走一步算一步,避免使用一些方法数较多的库,时时刻刻意识到这问题,让它慢一点到来,做我们能做的事,哦弥陀佛。

    使用dexcount-gradle-plugin 计算apk方法数

    用法
    在app/build.gradle添加

    buildscript {
        repositories {
            mavenCentral() // or jcenter()
        }
    
        dependencies {
            classpath 'com.getkeepsafe.dexcount:dexcount-gradle-plugin:0.3.0'
        }
    }
    
    apply plugin: 'com.getkeepsafe.dexcount'
    

    简单输出

    > ./gradlew assembleDebug
    
    ...buildspam...
    :app:compileDebugSources
    :app:preDexDebug UP-TO-DATE
    :app:dexDebug
    :app:packageDebug
    :app:zipalignDebug
    :app:assembleDebug
    Total methods in MyApp-debug-5.3.14.apk: 56538
    
    BUILD SUCCESSFUL
    
    Total time: 33.017 secs
    

    更多查看dexcount-gradle-plugin

    使用dex-method-count计算单个dex方法数

    解压apk文件可以看到classes.dex文件,如果使用了multidex可能会看到多个classses.dex,classes2.dex等。
    这里使用了网上找的一个脚本,很早之前看到的,找不到出处了,贴出来

    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() 
    

    dex-method-count.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
    
    
    

    用法:
    将上面两个文件拷贝到电脑(windows),文件名字和后缀都不要变,且放在同一个目录下,需要检测的dex文件也放在同一级目录,就像这样


    QQ截图20151116174811.png

    打开命令行并切到当前目录下,运行命令

    dex-method-count.bat classes.dex
    

    运行结果:Number of methods is 64595


    QQ截图20151116175052.png

    计算开源库方法数的网站

    http://www.methodscount.com/
    感谢Razerdp提供

    相关文章

      网友评论

      本文标题:android检测apk及dex方法数

      本文链接:https://www.haomeiwen.com/subject/mcikhttx.html