Android Studio 打包时动态修改aar 包名称

打包时动态修改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:
然后拆包查看:
这里写图片描述

发现在所有需要更改的地方都已经改好了。

没有更多推荐了,返回首页