我的65535解决方案2

我们公司有个小哥对代码是比较严谨的。上一个方案他觉得不优雅,需要其他同事安装 python3 ,需要添加dx到PATH中。

为了更优雅,我决定此方案中所有的功能都在 build.gradle 里实现。原理还是那个:

在gradle 的 transformClassesWithDexFor* task 之后,自己生成 classes2.dex ,放到 classes.dex 所在目录

因为,build.gradle 会被翻译成 java 代码,所以,这些功能是肯定能被实现的。在很多次调试之后,下面就是可用的版本啦。

这个方案的缺陷还是: classes2.dex 所包含的代码没有经过全局的 proguard ,体积会稍稍大一些(也不会太大,如果单独做过合适的proguard后)。

class ClassesDexListener implements TaskExecutionListener {
    String dxCmd = "";
    String dexBasePath = "";
    String libs2Path = ""
    public ClassesDexListener(String dx, String path, String libs2Path) {
        this.dxCmd = dx;
        this.dexBasePath = path;
        this.libs2Path = libs2Path;
    }
    @Override
    void beforeExecute(Task task) {
    }
    @Override
    void afterExecute(Task task, TaskState taskState) {
        if(task.name.contains("transformClassesWithDexFor")) {
            generateCreateDex2Task(task.name)
        }
    }
    // copy ext dex
    String getDexFolder(basePath) {
        File baseFile = new File(basePath)
        //println "find cleasses.dex under:" + baseFile.absolutePath
        if(baseFile.exists()) {
            File[] files = baseFile.listFiles();
            for(int i=0; i<files.size();i++) {
                def f = files[i]
                if (f.isFile() && f.name.equals("classes.dex")) {
                    return f.parentFile.absolutePath;
                } else if(f.isDirectory()) {
                    return getDexFolder(f.absolutePath)
                }
            }
        }
        return ""
    }


    void generateCreateDex2Task(String baseName) {
        println "generate classes2.dex for "+baseName
        println dxCmd
        String[] words = baseName.split("(?=\\p{Upper})")
        String last = words[words.length-1]
        last = last.toLowerCase()
        dexBasePath = dexBasePath + File.separator + last
        def destPath = getDexFolder(dexBasePath )
        destPath = destPath + File.separator + "classes2.dex"
        println destPath
        ProcessBuilder b = null;
        if(dxCmd.endsWith(".bat")) {
            b =  new ProcessBuilder(dxCmd, "--dex", "--output=\""+destPath+"\"", libs2Path);
        } else {
            b = new ProcessBuilder(dxCmd, "--dex", "--output="+destPath, libs2Path);
        }

        try {
            b.redirectErrorStream(true)
            Process p = b.start();
            if(p.getOutputStream() != null ) {
                BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()))
                while(true) {
                    String line = br.readLine()
                    if(line == null) {
                        break;
                    }
                    println line
                }
                p.waitFor()
                println "[dx] return: "+p.exitValue()
            } else {
                println "[dx] no output!"
            }

        } catch (Exception e) {
            println "exec dx error: "+e.class.toString() + e.getMessage()
        }

    }

}
String getDxCmd() {
    def sdkDir = android.getSdkDirectory().getAbsolutePath()
    def dxCmd = 'dx.bat'
    boolean found = false;
    for(File btools: file(sdkDir + File.separator + "build-tools").listFiles()) {
        if( btools.isDirectory()) {
            for(File file :btools.listFiles()) {
                if (file.isFile() && file.name.startsWith("dx")) {
                    dxCmd = file.absolutePath
                    found = true
                    break
                }
            }
            if (found){
                //break
            }
        }
    }
    return dxCmd
}
if (!overseaAutoMultidex || !chinaAutoMultidex) {
    def dxCmd = getDxCmd()
    String dexBasePath = file("build/intermediates/transforms/dex/").absolutePath
    if(!overseaAutoMultidex) {
        def libs2Path = file("libs2/oversea").absolutePath
        gradle.addListener new ClassesDexListener(dxCmd, dexBasePath+File.separator+"oversea", libs2Path)
    }
    if (!chinaAutoMultidex) {
        def libs2Path = file("libs2/china").absolutePath
        gradle.addListener new ClassesDexListener(dxCmd, dexBasePath+File.separator+"china", libs2Path)
    }
}

 把上面代码块添加到 build.gradle ,替换前一篇文章里的copy task 和 generate dex task 就可以了。

posted on 2016-04-28 15:35  Li.Stony 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/listony/p/5442884.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值