Android Studio gradle打包可执行jar包(包含第三方jar包)
1,背景
最近Android项目有用到动态加载jar,就是为了缩减apk体积,将一些插件功能分类打包到jar包,通过到服务器下载不同jar包来实现功能。在这一过程中遇到很多问题。
由于as不同版本会有很多诡异改变,本文中涉及相关路径可能在不同版本中表现不同,当前的操作环境为win10,Android Studio 3.1.4版本。
2,打包jar普通操作
def zipFile = file('build/intermediates/packaged-classes/debug/classes.jar')
task makeJar(type: Jar) {
archiveName = 'test.jar'
//如果之前存在,则先删除
delete 'build/libs/test.jar'
//设置拷贝的文件
from zipTree(zipFile)
from fileTree(dir: 'src/main', includes: ['assets/**'])
}
makeJar.dependsOn(build)
task makeDexJar(type: Exec){
def myCommond = [
'D:\\sdk\\build-tools\\26.0.2\\dx.bat', '--dex',
'--output=build/libs/testdex.jar',
'build/libs/test.jar'
]
commandLine myCommond
}
makeDexJar.dependsOn(makeJar)
以上gradle代码分为两个task,执行makeJar会在libs目录下生成不含dex的jar包,该包只能在其他工程中通过import引用,无法再Android中通过DexClassLoader加载。执行makeDexJar则会将makeJar生成的jar包打包优化成含class.dex的jar包,可以使用DexClassLoader加载。
3,jar包中需要包含第三方jar包
查询资料了解到,如果jar包中需要依赖第三方jar包则需要将其打包进自己的jar包中,最开始了解到:
from ('libs/dependencies.jar')
该种方式确实可以将第三方jar包包含进去,不过包含的形式是整个jar包被当做资源文件,并未当做源码,使用的时候就会报ClassNotFound的异常。
后来一直查询相关写法,找到:
from (project.zipTree("libs/dependencies.jar"))
改写法即可将整个代码添加到jar包中,可以调用第三方jar中的类了。
附上完整gradle代码:
def zipFile = file('build/intermediates/packaged-classes/debug/classes.jar')//指定build生成的jar的路径
task makeJar(type: Jar) {//生成不含dex的jar
archiveName = 'test.jar'
//如果之前存在,则先删除
delete 'build/libs/test.jar'
//设置拷贝的文件
from zipTree(zipFile)
from (project.zipTree("libs/dependencies.jar"))//将dependencies.jar作为源码添加到test.jar中
from fileTree(dir: 'src/main', includes: ['assets/**'])//指定添加assets目录下的所有文件
}
makeJar.dependsOn(build)//执行makeJar的时候会在之前执行build
task makeDexJar(type: Exec){
def myCommond = [
'D:\\sdk\\build-tools\\26.0.2\\dx.bat', '--dex',
'--output=build/libs/testdex.jar',
'build/libs/test.jar'//使用dx将jar中的代码优化成dex文件,该步骤可以手动命令行完成
]
commandLine myCommond
}
makeDexJar.dependsOn(makeJar)//执行makeDexJar的时候会在之前执行makeJar