多个module,输出一个jar包

目标:多个module,输出一个jar包

方法:shell脚本+gradle脚本实现

参考:Gradle实践之自定义打包jar+Log开关自动关闭

简介

在项目开发中要开发一个sdk,此lpsdk由多个module组成(如下图)。但是默认最终的lpsdk打出的jar包不包含它所依赖module的class文件,所以我想到的方案是解包每一个jar再把所有的class文件打包成一个all-in-one.jar输出。

此处输入图片的描述

使用

  1. build.gradle中引入makeJarConfig.gradle

    1
    2
    apply from: '../makeJarConfig.gradle'
    makeJarConfig()
  2. 执行makesdk.sh生成jar

原理

  1. 定义gradle taskmakeJar(方案一):

    • **注意:*不同版本的gradle编译生成.class的位置不一样。
      • 最新版build/intermediates/packaged-classes/release/classes.jar
      • 老版本build/intermediates/bundles/release/classes.jar
    • 所以只要copy出classes.jar即可。注意这个任务依赖build任务。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    task makeJar0(type: Copy, dependsOn: ['build']) {
    //删除存在的
    delete 'build/outputs/libs'
    //设置拷贝的文件
    from('build/intermediates/packaged-classes/release/')
    //打进jar包后的文件目录
    into('build/outputs/libs/')
    //将classes.jar放入build/libs/目录下
    //include ,exclude参数来设置过滤(我们只关心classes.jar这个文件)
    include('classes.jar')
    //重命名
    rename ('classes.jar', "${project.name}.jar")
    }
  2. 定义gradle taskmakeJar(方案二):
    方案一中classes.jar里有android特有的BuildConfig.class文件,有洁癖的人受不了。因为简单讲jar就是一堆.class文件组成的压缩文件,所以我们定义一个type: Jar的任务自己打包也可以。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    task makeJar(type: Jar, dependsOn: ['build']) {
    archiveName = "${project.name}.jar"
    from('build/intermediates/classes/release')
    destinationDir = file('build/outputs/libs')
    exclude('**/BuildConfig.class')
    exclude('**/BuildConfig\$*.class')
    exclude('**/R.class')
    exclude('**/R\$*.class')
    //空目录
    exclude('com/orhanobut')
    include('com/**/*.class')
    }
  3. 对每个module循环执行./gradlew xxxModule:makeJar,生成所有module的jar。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #./mergejars.sh "lpcommon" "lpsdkapi" "lpcontract" "lpaoa" "lpwireless" "lpsdkbase" "lpsdk"
    #在shell脚本中@表示传入的参数列表
    makeJar() {
    ./gradlew $1:makeJar
    cp $1/build/outputs/libs/* libout/
    }

    for val in $@
    do
    makeJar $val
    done
  4. 然后将这些jar解压。

    1
    2
    3
    4
    5
    #extract jars to *.class
    for val in $@
    do
    jar -xvf ../$val.jar
    done
  5. 最后打包成一个all-in-one.jar文件。

    1
    2
    #pack *.class to all-in-one.jar
    jar -cvf ../all-in-one.jar .

拿去不谢

  • makeJarConfig.gradle
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
def makeJarConfig() {
task makeJar0(type: Copy, dependsOn: ['build']) {
//删除存在的
delete 'build/outputs/libs'
//设置拷贝的文件
from('build/intermediates/packaged-classes/release/')
//打进jar包后的文件目录
into('build/outputs/libs/')
//将classes.jar放入build/libs/目录下
//include ,exclude参数来设置过滤
//(我们只关心classes.jar这个文件)
include('classes.jar')
//重命名
rename ('classes.jar', "${project.name}.jar")
}


//去掉BuildConfig.class
task makeJar(type: Jar, dependsOn: ['build']) {
archiveName = "${project.name}.jar"
from('build/intermediates/classes/release')
destinationDir = file('build/outputs/libs')
exclude('**/BuildConfig.class')
exclude('**/BuildConfig\$*.class')
exclude('**/R.class')
exclude('**/R\$*.class')
//空目录
exclude('com/orhanobut')
include('com/**/*.class')
}
}
  • mergejars.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#!/usr/bin/env bash

cleanAll() {
echo "clean all ......"
for val in $@
do
./gradlew $val:clean
done
}


makeJar() {
./gradlew $1:makeJar -x lint
cp $1/build/outputs/libs/* libout/
}

makeJars() {
echo "makejars ......"
rm -rf libout
mkdir libout

for val in $@
do
makeJar $val
done
}


makeAllInOne() {
echo "makeAllInOne ......"
cd libout
rm -rf tmp
mkdir tmp
cd tmp

#extract jars to *.class
for val in $@
do
jar -xvf ../$val.jar
done

#pack *.class to all-in-one.jar
jar -cvf ../all-in-one.jar .
cd ..
rm -rf tmp
cd ..
}

cleanAll $@

makeJars $@

makeAllInOne $@
  • makesdk.sh
1
2
3
4
#!/usr/bin/env bash
./mergejars.sh "lpcommon" "lpsdkapi" "lpcontract" "lpaoa" "lpwireless" "lpsdkbase" "lpsdk"

echo -e "\e[36m^_^ finished : libout/all-in-one.jar \e[0m"