最近在使用Android Studio时,碰到了打包Jar文件的问题,看了一些资料,自己捣鼓出来了。想想总结一下吧,免得下次忘了。
一、常用的导出Jar文件的方法
1.第一种比较繁琐的方法:
思路是:在需要导出Jar文件的Module下面的build.gradle文件中编写导出Jar文件的任务,然后执行此任务,获得Jar文件。
废话不说直接上干货:
1) 写task
// task 后面跟的是任务名字,自己去一个就好,命名一般就像类名的命名一样,驼峰命名法
task buildJar (dependsOn : ['compileReleaseJavaWithJavac'], type : Jar) {
// 1.设置导出的Jar文件的名称
archiveName = "自己命名Jar文件.jar"
// 2.需要打包的资源所有的资源路径
from('build/intermediates/classes/release')
// 3.指定导出的Jar文件存放的位置,如果没有指定则默认存放在工程的build/libs目录下
destinationDir = file('.../libs')
// 4.可以去除你不想打包的类(自己根据需要来编写)
exclude "com/example/xxx/BuildConfig.class"
exclude('**/R.class')
exclude('**/R\$.class')
// 5.添加要包含的类
include "**/*.*"
include('com/example/xxx/xxx.class')
// 再写一个task,这个task是用来混淆
// 注意此处的dependsOn对应的值和上一个task的名字有关,我这里都写的是buildJar
task proguardJar(type : ProGuardTask, dependsOn : ['buildJar']) {
// println('proguard ' + project.name + ' .jar')
// 配置ProGuard文件,使用默认的文件
configuration android.getDefaultProguardFile('proguard-android.txt')
// 加载各模块的 proguard文件
configuration 'proguard-rules.pro'
// 设置导出的Jar文件路径和名称
String inJar = buildJar,archivePath.getAbsolutePath()
injars inJar
outjars injar,substring(0, inJar.lastIndexOf('-')) + "-release.jar")
// 设置不删除未引用的类或者资源
dontshrink
// 运行时Jar包不混淆
Plugin plugin = getPlugins().hasPlugin(AppPlugin)?
getPlugins().findPlugin(AppPlugin):
getPlugins().findPlugin(LibraryPlugin)
if (plugin != null) {
List<String> runtimeJarList
if (plugin.getMetaClass().getMetaMethod("getRuntimeJarList")) {
runtimeJarList = plugin.getRuntimeJarList()
} else if (android.getMetaClass.getMetaMethod("getBootClasspath")) {
runtimeJarList = android.getBootClasspath()
} else {
runtimeJarList = plugin.getBootClasspath()
}
for (String runtimeJar : runtimeJarList) {
libraryjars(runtimeJar)
}
}
}
2)执行task
有两种方式:
第一种是在Android Studio底部的工具中找到Terminal(相当于命令行),执行命令。
./gradlew makeJar //gradlew 后面跟的是你的task的名字
来张图看一下:
第二种方式是在Android Studio右侧找到Gradle Projects工具,找到编写的task,点击运行
2.一种稍微简单的方法:
基本原理:因为在整个工程build的时,也会生成jar文件,在其所在的Module的build/intermediates/bundles/release/classes.jar。值得注意的是,这个jar文件是未经混淆的,此种打包方式就是重新打包并修改Jar文件名、进行混淆。
apply plugin 'com.novoda.bintray-release'
android {
...
lintOptions {
abortOnError false
warning 'InvalidPackage'
}
}
task makeJar(type : Copy) {
delete 'build/output/xxx.jar'
from('build/intermediates/bundles/release/')
configuration 'proguard-rules.pro'
into('build/output/')
include('classes.jar')
rename('classes.jar', 'xxx-x_x_x.jar')
}
// 在GitHub上发布源码框架
publish {
uesrOrg = 'bintray.com用户名'
groupId = 'jcenter上的路径'
artifactId = '项目名称'
publishVersion = '版本号x.x.x'
desc = '描述'
website = 'https://github.com/github用户名/项目名'
}
二、混淆规则文件的常见配置
-libraryjars 'JDK的路径/.../rt.jar' # 指向JDK rt.jar
-libraryjars 'Android SDK的路径/platforms/android-版本号(比如24)/android.jar' # 指向 android.jar
-optimizationpasses 5 # 指定代码的迭代优化次数
-dontusemixedcaseclassnames # 不使用大小写名称的类名
-dontskipnonpubliclibraryclasses # 不忽略非公共的库类
-dontpreverify # 混淆时是否做预校验
-verbose # 混淆时是否记录日志
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/* # 优化选项
# 各种keep表示不需要混淆的类和方法
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.view.View {
public <init>(android.content.Context);
public <init>(android.content.Context,android.util.AttributeSet);
public <init>(android.content.Context,android.util.AttributeSet,int);
public void set*(...);
}
-keepclasseswithmembers class * {
public <init>(android.content.Context,android.util.AttributeSet);
}
-keepclasseswithmembers class * {
public <init>(android.content.Context,android.util.AttributeSet,int);
}
-keepclassmembers class * extends android.content.Context {
public void *(android.view.View);
public void *(android.view.MenuItem);
}
-keepclassmembers class * extends android.os.Parcelable {
static ** CREATOR;
}
-keepclassmembers class **.R$* {
public static <fields>;
}
-keepclassmembers class * {
@android.webkit.JavascriptInterface
<methods>;
}