打包时动态修改aar 包名称
利用AndroidStudio 打包aar时,动态修改aar的路径名称。
例如:rename com.android.aar to com.google.aar
如果这个包中有一个类(ReName.java),那么它的包名便由com.android.aar 变为了 com.google.aar。
这个功能一般都是SDK开发在使用。最近一年都在为公司开发以及维护某SDK,其中产生了很多版本。
例如对内使用的,对外部使用。
有的时候对外发布包的时候,需要修改SDK的包名,使其不和内部使用的版本不同。
修改SDK的包名和修改APK的包名不同,修改APK的包名主要是修改其applicationId,可以通过配置productFlavors,指定不同的flavor使用不同的applicationId就可以了。
修改SDK的包名主要是想修改其引用路径。
一、前期准备
1、利用Android studio建立一个项目
这是一个随意的项目,目的是为了承载Module(即SDK),同时这个项目主要用于测试SDK使用。
2、建立一个Module。
这个便是SDK了,在其内部书写SDK的代码。在这里我给这个Module命名为:task_lib 。
其目录为这样:
可以看到我们为其在src下面建立了三个存放代码的文件夹:分别是inner, main, outter。
inner 为对内版本,outter为对外版本。
在我们对外发布SDK时,需要修改其包名,不希望其包名为com.rename.task,我们会将其修改为com.vaga.task。
3、在SDK目录下的build.gradle中为其建立productFlavors,以及sourceSets。
在3.0版本后,在建立productFlavors时,需要为其指定flavorDimensions。(具体可以相见其文档)
在我们这里为inner,outter制定相同的dimension,表示其是不同的flavor。这个要根据具体的需求来做了,这里相对随意。
这样准备工作就做完了。
二、添加配置文件
1、引入jarjar-1.4.jar
该jar包用于更改jar包名称。
2、准备几个类
3、为out flavor 建立一个混淆文件:out-proguard-rules.pro
引入:
这样在build out 的release 包的时候,会走这个混淆文件。
在混淆时,我们可以指定修改某个类的名字。
利用在我们这里,我们希望将ReNameSDK类名改为VagaSDK。
在混淆文件中需要先将其keep出来,不能混淆,否则改名字时找不到这个类。
4、新建一个rule 文件。
这我们这里命名为:out-rule.txt
jarjar在修改jar名时需要rule文件,指导其修改哪些包名,改为什么。
在我们这里添加:
rule com.rename.task.** com.vaga.task.@1
将com.rename.task 及一下,改为 com.vaga.task
5、新建out-mapping.txt文件
我们可以在mapping文件中指定更改某个类名,甚至方法的名称。
例如:
com.rename.task.ReNameSDK -> com.vaga.task.VagaSDK:
具体的格式可以去参考mapping文件。
out-mapping 文件想要生效需要在out-proguard-rules.pro中指定:
-applymapping out-mapping.txt
三、build.gradle
1、gradle中添加两个task:
task renameExtractAar(dependsOn: 'assembleApiOutterRelease', type: Copy) {
outputs.upToDateWhen { false }
println(project.buildDir.getAbsolutePath())
File processAarFile = new File(project.buildDir, "outputs/aar/task_lib-api-outter-release.aar")
File workDir = new File(project.buildDir, "outputs/aar/workDir")
String jarjarFile = "jarjar-1.4.jar"
from zipTree(processAarFile)
into workDir
doFirst {
if (workDir.exists()) {
workDir.deleteDir()
println("extract dir deleted")
}
}
doLast {
File classesJar = new File(workDir, "classes.jar")
File workJar = new File(workDir, "classes-original.jar")
boolean result = classesJar.renameTo(workJar)
println("rename result " + result)
project.exec {
executable = 'java'
args += '-jar'
args += jarjarFile
args += 'process'
args += 'out-rule.txt'
args += workJar.getAbsolutePath()
args += classesJar.getAbsolutePath()
}
workJar.delete()
}
}
task outAar(dependsOn: renameExtractAar, type: Zip) {
outputs.upToDateWhen { false }
println(project.buildDir.getAbsolutePath())
File aarDir = new File(project.buildDir, "outputs/aar")
File workDir = new File(aarDir, "workDir")
from workDir
archiveName "out-release.aar"
destinationDir aarDir
}
2、task 依赖 renameExtractAar, renameExtractAar依赖 assembleApiOutterRelease。
运行task outAar 就可以在outputs/aar 下面看到 out-release.aar 了。
拆开out-release.aar看一下:
首先可以看到包名变了,变成了com.vage.task。
ReNameSDK名称也变了。
3、完善
我们看一下manifest文件:
发现两个问题:
(1)、package名称没有变,我们也无法改变其名称。
而这个package主要影响res的引用。问题不大,如果不想暴露内部的package,可以起一个中立一点的名字,例如com.google 哈哈。
(2)、activity 在mainfest中声明不对,因为我们已经将其改为 com.vaga.task。
这里还用com.rename.task 很显然会出问题。
所以这里我们可以利用: manifestPlaceholders
即是manifest占位符。
首先我们可以在defaultConfig中声明:
manifestPlaceholders = [pkgName: “com.rename.task”]
声明其默认的包名。
而后在out 中更改其包名:
改为com.vaga.task。
然后在:
maifest中这样更改:
<activity android:name="${pkgName}.RenameActivity"/>
就可以了。
四、再次运行task outAar:
然后拆包查看:
发现在所有需要更改的地方都已经改好了。