Android Studio让module library application并存的尝试

2019-02-27 16:57:20 浏览数 (1)

在做UAF的时候,我产生了一个需求:我希望我可以把demoUAF ClientUAF ASM分别打包成3个apk,又可以打包成1个apk。当分别打包的时候,UAF Client/UAF ASM是application;统一打包的时候,UAF Client/UAF ASM是library。我开始进行尝试。

方案1: 通过apply library 和 application plugin进行配置

初步想法

我希望在debug的时候,UAF Client/UAF ASM的build.gradle apply plugin: 'com.android.library',release的时候apply plugin: 'com.android.application'。我找到识别debug和release的方法:

var debug = gradle.getStartParameter().getTaskRequests().toString().contains("Debug") if (debug) { apply plugin: 'com.android.library' } else { apply plugin: 'com.android.application' }

1234567

var debug = gradle.getStartParameter().getTaskRequests().toString().contains("Debug")if (debug) {    apply plugin: 'com.android.library'} else {    apply plugin: 'com.android.application'}

因为我需要在Generate Signed APK中可以选择UAF Client导出apk,所以需要默认是application。(gradle进行sync的时候会进行一次配置,此时debug变量恒为false)

因为library module无可以配置applicationId,所以还需要:

android { defaultConfig { if (!debug) { applicationId "com.*****" } // ...... } }

123456789

android {    defaultConfig {        if (!debug) {            applicationId "com.*****"        }        // ......    }}

然后在demo中加入依赖:

debugCompile project(':asm') debugCompile project(':client')

123

debugCompile project(':asm')debugCompile project(':client')

存在问题

如此配置导致的问题是gradle sync now失败。报错是“demo无法依赖一个application的module”。但不sync直接运行demo和Generate Signed APK都是可以的。一开始我以为是我debug判断条件有问题,使用println打印信息发现没有输出。

后来了解到gradle sync会遍历一遍gradle文件进行配置,再执行常规编译。在遍历过程中并没有**Debug这样的task进行判断,所以此时UAF Client/ASM是当作application来处理的。

初步想法改进

那为了可以sync成功,我只能把默认改为library了。

var debug = gradle.getStartParameter().getTaskRequests().toString().contains("Debug") if (!debug) { apply plugin: 'com.android.application' } else { apply plugin: 'com.android.library' }

1234567

var debug = gradle.getStartParameter().getTaskRequests().toString().contains("Debug")if (!debug) {    apply plugin: 'com.android.application'} else {    apply plugin: 'com.android.library'}

这样一来,我就无法使用Generate Signed APK导出UAF Client/UAF ASM了。但同时我发现了一个有趣的现象:在这个配置之下,我导出demo-release.apk的同时,UAF Client和UAF ASM的release.apk也一并导出了。我猜测是配置过程由于我判断条件的干扰导致的。我试着导出demo-debug.apk,UAF Client和UAF ASM还是导出release.apk,但大小和原来不一样了(原本debug版本是带日志的,会大一点)。生成物是正确的,但名字不对。

然后我把混合/独立的判断条件从debug/release改为flavor控制之后,出现了更多的问题。

结论

不可行。

方案2:新建一个module,引用原library/复用原library代码

方案2一听就是靠谱的。通过新建一个module,引用原library module,专门用于导出apk;或通过配置,复用library module的main文件夹:

android { sourceSets { main.setRoot("../asm/src/main") } }

123456

android {    sourceSets {        main.setRoot("../asm/src/main")    }}

结论

可行。

思考

为什么我会没想到简单的方案2,而是在方案1中纠结良久,不可自拔呢?因为我不久之前在某个网站(貌似是简书)上看过一篇文章,它最后说明了如何调试多个apk,就是debug的时候把application的module改为library module,release的时候再独立打包。我只留了个印象,没有收藏这篇文章。而到了用到这个的时候我找不到原文章了,但我内心会一直认为该方案可行,且解决方法优雅。

我再想了想,其实合并多个apk对调试并没有什么优势,这样的编译时间反而更长,只让修改部分的apk重新安装还更快速。。

——————————

我再想了想,那篇文章好像讲的是多个独立模块调试时,可以拆开apk独立运行,不用一点修改就要重新打包整个工程,以提高速度。。不过有了 instant run 这个技巧也不是特别有用了。

0 人点赞