Android Studio 使用 Gradle 打包 Jar-IT蓝豹
2015-10-07 11:28
966 查看
Android Studio 打 Jar 包一直是一个麻烦的事,按照网上现有的教程,打包一个混淆的 jar 需要完成下列步骤:
将
plugin 修改为library后 build 出 aar,再提取 aar 里面的 classes.jar
使用
jarjar 等工具剔除多余的 class
对第二步得到的
jar 进行混淆
无论哪一步,所做的工作量都不少。于我个人而言,相当麻烦,于是花了些时间研究了下 Gradle 打 Jar 包。
build.gradle
import com.android.build.gradle.AppPlugin
import proguard.gradle.ProGuardTask
apply
plugin:'com.android.application'
android
{
compileSdkVersion
22
buildToolsVersion
"22.0.1"
defaultConfig
{
applicationId
"org.chaos.demo.jar"
minSdkVersion
22
targetSdkVersion
22
versionCode
1
versionName
"1.0"
}
buildTypes
{
release
{
minifyEnabled
true
proguardFiles
getDefaultProguardFile('proguard-android.txt'),'proguard-rules.pro'
}
}
}
dependencies
{
compile
fileTree(dir:'libs', include:['*.jar'])
}
//dependsOn
可根据实际需要增加或更改
task
buildJar(dependsOn:['compileReleaseJava'], type:Jar){
appendix
="demo"
baseName
="androidJar"
version
="1.0.0"
classifier
="release"
//后缀名
extension
="jar"
//最终的
Jar 包名,如果没设置,默认为 [baseName]-[appendix]-[version]-[classifier].[extension]
archiveName
="AndroidJarDemo.jar"
//需打包的资源所在的路径集
def srcClassDir =[project.buildDir.absolutePath
+"/intermediates/classes/release"];
//初始化资源路径集
from srcClassDir
//去除路径集下部分的资源
//
exclude "org/chaos/demo/jar/MainActivity.class"
//
exclude "org/chaos/demo/jar/MainActivity/$*.class"
exclude
"org/chaos/demo/jar/BuildConfig.class"
exclude
"org/chaos/demo/jar/BuildConfig/$*.class"
exclude
"**/R.class"
exclude
"**/R/$*.class"
//只导入资源路径集下的部分资源
include
"org/chaos/demo/jar/**/*.class"
//注:
exclude include 支持可变长参数
}
task
proguardJar(dependsOn:['buildJar'], type:ProGuardTask){
//Android
默认的 proguard 文件
configuration
android.getDefaultProguardFile('proguard-android.txt')
//会根据该文件对
Jar 进行混淆,注意:需要在 manifest 注册的组件也要加入该文件中
configuration
'proguard-rules.pro'
String inJar = buildJar.archivePath.getAbsolutePath()
//输入
jar
injars
inJar
//输出
jar
outjars
inJar.substring(0, inJar.lastIndexOf('/'))+"/proguard-${buildJar.archiveName}"
//设置不删除未引用的资源(类,方法等)
dontshrink
AppPlugin appPlugin = getPlugins().findPlugin(AppPlugin)
if(appPlugin
!=null){
List<String> runtimeJarList
if(appPlugin.getMetaClass().getMetaMethod("getRuntimeJarList")){
runtimeJarList
= appPlugin.getRuntimeJarList()
}elseif(android.getMetaClass().getMetaMethod("getBootClasspath")){
runtimeJarList
= android.getBootClasspath()
}else{
runtimeJarList
= appPlugin.getBootClasspath()
}
for(String runtimeJar : runtimeJarList){
//给
proguard 添加 runtime
libraryjars(runtimeJar)
}
}
}
manifest 中已注册的组件的规则文件。然而我们的 task 只是依赖于compileReleaseJava(该 task 在执行 aapt 前),
Gradle Android Plugin 中配置上述 aapt 生成的规则文件的代码如下:
BasePlugin.groovy
protectedFile createProguardTasks(@NonNullBaseVariantData variantData,
@NullableBaseVariantData testedVariantData){
......
//
also the config file output by aapt
proguardTask.configuration(variantData.proce***esourcesTask.proguardOutputFile)
......
}
碍于技术原因,获取不到proce***esourcesTask的实例,所以目前只能先添加对应的组件到规则文件中,还望知道怎么获取的朋友能够分享下,谢谢。
gradle
buildJar
或
./gradlew
buildjar
需要混淆则运行
gradle
proguardJar
或
./gradlew
proguardJar
的路径,但是团队每个人都有自己的安装习惯,路径不一定一致,于是乎看源码翻了一段时间才找到相应的代码。至于想更多个性化的朋友,建议从源码入手。
将
plugin 修改为library后 build 出 aar,再提取 aar 里面的 classes.jar
使用
jarjar 等工具剔除多余的 class
对第二步得到的
jar 进行混淆
无论哪一步,所做的工作量都不少。于我个人而言,相当麻烦,于是花了些时间研究了下 Gradle 打 Jar 包。
代码
废话不多说,先上代码( 注 :只在 Gradle Android Plugin 1.2.3 测试过)build.gradle
import com.android.build.gradle.AppPlugin
import proguard.gradle.ProGuardTask
apply
plugin:'com.android.application'
android
{
compileSdkVersion
22
buildToolsVersion
"22.0.1"
defaultConfig
{
applicationId
"org.chaos.demo.jar"
minSdkVersion
22
targetSdkVersion
22
versionCode
1
versionName
"1.0"
}
buildTypes
{
release
{
minifyEnabled
true
proguardFiles
getDefaultProguardFile('proguard-android.txt'),'proguard-rules.pro'
}
}
}
dependencies
{
compile
fileTree(dir:'libs', include:['*.jar'])
}
//dependsOn
可根据实际需要增加或更改
task
buildJar(dependsOn:['compileReleaseJava'], type:Jar){
appendix
="demo"
baseName
="androidJar"
version
="1.0.0"
classifier
="release"
//后缀名
extension
="jar"
//最终的
Jar 包名,如果没设置,默认为 [baseName]-[appendix]-[version]-[classifier].[extension]
archiveName
="AndroidJarDemo.jar"
//需打包的资源所在的路径集
def srcClassDir =[project.buildDir.absolutePath
+"/intermediates/classes/release"];
//初始化资源路径集
from srcClassDir
//去除路径集下部分的资源
//
exclude "org/chaos/demo/jar/MainActivity.class"
//
exclude "org/chaos/demo/jar/MainActivity/$*.class"
exclude
"org/chaos/demo/jar/BuildConfig.class"
exclude
"org/chaos/demo/jar/BuildConfig/$*.class"
exclude
"**/R.class"
exclude
"**/R/$*.class"
//只导入资源路径集下的部分资源
include
"org/chaos/demo/jar/**/*.class"
//注:
exclude include 支持可变长参数
}
task
proguardJar(dependsOn:['buildJar'], type:ProGuardTask){
//Android
默认的 proguard 文件
configuration
android.getDefaultProguardFile('proguard-android.txt')
//会根据该文件对
Jar 进行混淆,注意:需要在 manifest 注册的组件也要加入该文件中
configuration
'proguard-rules.pro'
String inJar = buildJar.archivePath.getAbsolutePath()
//输入
jar
injars
inJar
//输出
jar
outjars
inJar.substring(0, inJar.lastIndexOf('/'))+"/proguard-${buildJar.archiveName}"
//设置不删除未引用的资源(类,方法等)
dontshrink
AppPlugin appPlugin = getPlugins().findPlugin(AppPlugin)
if(appPlugin
!=null){
List<String> runtimeJarList
if(appPlugin.getMetaClass().getMetaMethod("getRuntimeJarList")){
runtimeJarList
= appPlugin.getRuntimeJarList()
}elseif(android.getMetaClass().getMetaMethod("getBootClasspath")){
runtimeJarList
= android.getBootClasspath()
}else{
runtimeJarList
= appPlugin.getBootClasspath()
}
for(String runtimeJar : runtimeJarList){
//给
proguard 添加 runtime
libraryjars(runtimeJar)
}
}
}
为什么已在 manifest 注册的组件需要在 .pro 文件声明对应的混淆规则?
可能各位注意到 proguardJar task 的第二行注释,在 apk 的打包过程中,aapt 会在解析 manifest 后生成一个用于不混淆manifest 中已注册的组件的规则文件。然而我们的 task 只是依赖于compileReleaseJava(该 task 在执行 aapt 前),
Gradle Android Plugin 中配置上述 aapt 生成的规则文件的代码如下:
BasePlugin.groovy
protectedFile createProguardTasks(@NonNullBaseVariantData variantData,
@NullableBaseVariantData testedVariantData){
......
//
also the config file output by aapt
proguardTask.configuration(variantData.proce***esourcesTask.proguardOutputFile)
......
}
碍于技术原因,获取不到proce***esourcesTask的实例,所以目前只能先添加对应的组件到规则文件中,还望知道怎么获取的朋友能够分享下,谢谢。
使用方法
不需要混淆则运行命令gradle
buildJar
或
./gradlew
buildjar
需要混淆则运行
gradle
proguardJar
或
./gradlew
proguardJar
总结
buildJar这部分相对比较简单,很多内容网上都有教程。关键在于混淆,由于需要导入 runtime 相关的 jar,虽说可以写死 runtime的路径,但是团队每个人都有自己的安装习惯,路径不一定一致,于是乎看源码翻了一段时间才找到相应的代码。至于想更多个性化的朋友,建议从源码入手。
相关文章推荐
- SourceProvider.getJniDirectories
- 执行失败的任务 ': processDebugManifest'
- Android Studio使用教程(六):Gradle多渠道打包
- Android 中动态加载.jar的实现步骤
- java使用命令行打包JAR
- 用代码更新你的jar包
- 用Java连接sqlserver数据库时候几个jar包的区别分析
- Android Studio注释模板介绍
- 基于将Android工程做成jar包和资源文件的解决方法
- jar包双击执行程序的方法
- Android Studio使用教程(四):Gradle基础
- Android Studio使用教程(五):Gradle命令详解和导入第三方包
- 在eclipse导入Java的jar包的方法JDBC(图文说明)
- 从Java的jar文件中读取数据的方法
- Jar打包用法详解
- 基于Java的打包jar、war、ear包的作用与区别详解
- dom4j从jar包中读取xml文件的方法
- java生成jar包的方法
- jar命令的用法详解
- 将Python代码打包为jar软件的简单方法