Android Studio 打 Jar 包一直是一个麻烦的事,按照网上现有的教程,打包一个混淆的 jar 需要完成下列步骤:

1.将 plugin 修改为 library 后 build 出 aar,再提取 aar 里面的 classes.jar

2.使用 jarjar 等工具剔除多余的 class

3.对第二步得到的 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 runtimeJarList

if (appPlugin.getMetaClass().getMetaMethod(“getRuntimeJarList”)) {

runtimeJarList = appPlugin.getRuntimeJarList()

} else if (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 中已注册的组件的规则文件。Gradle Android Plugin 中配置上述 aapt 生成的规则文件的代码如下:

BasePlugin.groovy

protected File createProguardTasks(@NonNull BaseVariantData variantData,

@Nullable BaseVariantData testedVariantData) {

……

// also the config file output by aapt

proguardTask.configuration(variantData.processResourcesTask.proguardOutputFile)

……

}

碍于个人能力原因,获取不到 processResourcesTask 的实例,所以目前只能先添加对应的组件到规则文件中,还望知道怎么获取的朋友能够分享下,谢谢。

使用方法

不需要混淆则运行命令

gradle buildJar



./gradlew buildjar

需要混淆则运行

gradle proguardJar



./gradlew proguardJar

最后

buildJar 这部分相对比较简单,很多内容网上都有教程。关键在于混淆,由于团队每个人都有自己的安装习惯,JDK、Android SDK 路径不一定一致,并不能直接写死 runtime 的路径,最后直接看 Android Plugin 源码才写出了 proguardJar task。

Android Studio 使用 Gradle 打包 Jar的更多相关文章

  1. android studio 使用gradle 导出jar包,并打包assets目录

    警告:本文年久失修. 随着android studio的升级 ,gradle的升级,严格按照本文的代码去做可能不会成功,希望依然可以作为解决问题的思路. 最近项目在做一个sdk,供别的开发者使用,所以 ...

  2. [转]--android studio 使用gradle 导出jar包,并打包assets目录

    转自: http://www.cnblogs.com/wuya/p/android-studio-gradle-export-jar-assets.html   最近项目在做一个sdk,供别的开发者使 ...

  3. 在Android studio中用gradle打 jar 包(Mac下)

    这两天公司要重构项目,以前的项目在eclipse上,准备迁移到Android studio上,需要对项目打包,于是我学习了Android studio中gradle打包的内容.我在公司用的Mac,在家 ...

  4. Android 项目利用 Android Studio 和 Gradle 打包多版本APK

    在项目开发过程中,经常会有需要打包不同版本的 APK 的需求. 比如 debug版,release版,dev版等等. 有时候不同的版本中使用到的不同的服务端api域名也不相同. 比如 debug_ap ...

  5. 利用 Android Studio 和 Gradle 打包多版本APK

    在项目开发过程中,经常会有需要打包不同版本的 APK 的需求. 比如 debug版,release版,dev版等等. 有时候不同的版本中使用到的不同的服务端api域名也不相同. 比如 debug_ap ...

  6. android studio application应用打包jar

    转载: https://blog.csdn.net/xiayiye5/article/details/79639044 首先我们来说下打成jar包的分类: 1.application应用打成jar包 ...

  7. Android studio下gradle Robolectric单元测试配置

    android studio下gradle Robolectric单元测试配置 1.Robolectric Robolectric是一个基于junit之上的单元测试框架.它并不依赖于Android提供 ...

  8. Android Studio(九):引用jar及so文件

    Android Studio相关博客: Android Studio(一):介绍.安装.配置 Android Studio(二):快捷键设置.插件安装 Android Studio(三):设置Andr ...

  9. Android Studio :Android Studio 与 Gradle 深入【二】

    转载:http://www.apkbus.com/forum.php?mod=viewthread&tid=255063&extra=page%3D2%26filter%3Dautho ...

随机推荐

  1. Mysql--开篇&目录

    Mysql 现在是互联网公司中使用得非常广泛的数据库产品了,开源.免费.小巧.易用等诸多特性奠定了其夯实的基础.自己从事 JavaWeb 也有一段时间了,工作中也是用的 Mysql,也会涉及到分析.慢 ...

  2. 使用webpack-dev-server设置反向代理解决前端跨域问题

    webpack-dev-server是一个小型的Node.js Express服务器,它使用webpack-dev-middleware来服务于webpack的包,除此自外,它还有一个通过Sock.j ...

  3. AJAX 向后台发送带 List 集合的对象

    现有基类: public class School { int name; int address; List<Student> students = new ArrayList<S ...

  4. Java Socket通信代码片

    package zhang; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOExcept ...

  5. merge into的用法及10g新特性总结

    merge into 的作用: 将源数据(来源于实际的表,视图,子查询)更新或插入到指定的表中(必须实际存在),依赖于on条件,好处是避免了多个insert 和update操作. merge是一个目标 ...

  6. jQuery 遍历 – 后代

    后代是子.孙.曾孙等等. 通过 jQuery,您能够向下遍历 DOM 树,以查找元素的后代. 向下遍历 DOM 树 下面是两个用于向下遍历 DOM 树的 jQuery 方法: children() f ...

  7. Android广播的发送与接收

    Android广播的发送与接收 效果图 广播发送 广播分为有序广播和无序广播 有序广播与无序广播的区别 无序广播:只要是广播接收者指定了接收的事件类型,就可以接收到发送出来的广播消息.不能修改消息. ...

  8. hive表的存储格式; ORC格式的使用

    hive表的源文件存储格式有几类: 1.TEXTFILE 默认格式,建表时不指定默认为这个格式,导入数据时会直接把数据文件拷贝到hdfs上不进行处理.源文件可以直接通过hadoop fs -cat 查 ...

  9. CDH集群安装&测试总结

    0.绪论 之前完全没有接触过大数据相关的东西,都是书上啊,媒体上各种吹嘘啊,我对大数据,集群啊,分布式计算等等概念真是高山仰止,充满了仰望之情,觉得这些东西是这样的: 当我搭建的过程中,发现这些东西是 ...

  10. java获取ip的方式,注意多级代理的方式获取

    public String getIP() { String clientIP = ServletActionContext.getRequest().getHeader("x-forwar ...