参考链接https://www.jianshu.com/p/e9d3c57ab92f
Android Studio 中可通过配置 proguard-rules.pro 对生成的 apk 和 jar 进行混淆。
1.Android Studio 创建Module后,会自动生成 proguard-rules.pro 文件,在该文件中进行混淆的配置。如图
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
#=========================================基本配置========================================#
# 代码混淆压缩比,在0~7之间,默认为5,一般不做修改
-optimizationpasses 5
#不跳过非公共的库的类成员
-dontskipnonpubliclibraryclassmembers
# 指定不去忽略非公共库的类
#默认跳过,有些情况下编写的代码与类库中的类在同一个包下,并且持有包内容的引用,此时就需要提示不跳过
-dontskipnonpubliclibraryclasses
#混淆时不使用大小写混合,混淆后的类名为小写(大小写混淆容易导致class文件相互覆盖)
-dontusemixedcaseclassnames
# 这句话能够使我们的项目混淆后产生映射文件
# 包含有类名->混淆后类名的映射关系
-verbose
-printmapping proguardMapping.txt
# 不做预校验,preverify是proguard的四个步骤之一,Android不需要preverify,去掉这一步能够加快混淆速度。
-dontpreverify
# 保留Annotation不混淆
-keepattributes *Annotation*,InnerClasses
# 避免混淆泛型
-keepattributes Signature
# 抛出异常时保留代码行号
-keepattributes SourceFile,LineNumberTable
# 指定混淆是采用的算法,后面的参数是一个过滤器
# 这个过滤器是谷歌推荐的算法,一般不做更改
-optimizations !code/simplification/cast,!field/*,!class/merging/*
#忽略警告 (慎用)
#-ignorewarnings
#输出apk包内所有的class的内部结构
#-dump class_files.txt
#未混淆的类和成员
#-printseeds seeds.txt
#列出从apk中删除的代码
#-printusage unused.txt
#############################################
#
# Android开发中一些需要保留的公共部分
#
#############################################
# 保留我们使用的四大组件,自定义的Application等等这些类不被混淆
# 因为这些子类都有可能被外部调用
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Appliction
-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.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class * extends android.view.View
-keep public class com.android.vending.licensing.ILicensingService
-keep public class android.os.Handler.**
-keep public class * extends android.os.Handler
# 保留support下的所有类及其内部类
-keep class android.support.** {*;}
# 保留继承的
-keep public class * extends android.support.v4.**
-keep public class * extends android.support.v7.**
-keep public class * extends android.support.annotation.**
# 保留R下面的资源
-keep class **.R$* {*;}
# 保留本地native方法不被混淆
-keepclasseswithmembernames class * {
native <methods>;
}
# 保留在Activity中的方法参数是view的方法,
# 这样以来我们在layout中写的onClick就不会被影响
-keepclassmembers class * extends android.app.Activity{
public void *(android.view.View);
}
# 保留枚举类不被混淆
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
# 保留我们自定义控件(继承自View)不被混淆
-keep public class * extends android.view.View{
*** get*();
void set*(***);
public <init>(android.content.Context);
public <init>(android.content.Context, android.util.AttributeSet);
public <init>(android.content.Context, android.util.AttributeSet, int);
}
# 保留Parcelable序列化类不被混淆
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
# 保留Serializable序列化的类不被混淆
-keepnames class * implements java.io.Serializable
-keepclassmembers class * implements java.io.Serializable {
static final long serialVersionUID;
private static final java.io.ObjectStreamField[] serialPersistentFields;
!static !transient <fields>;
!private <fields>;
!private <methods>;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
java.lang.Object writeReplace();
java.lang.Object readResolve();
}
# 对于带有回调函数的onXXEvent、**On*Listener的,不能被混淆
-keepclassmembers class * {
void *(**On*Event);
void *(**On*Listener);
void *(**on**);
}
# webView处理,项目中没有使用到webView忽略即可
-keepclassmembers class fqcn.of.javascript.interface.for.webview {
public *;
}
-keepclassmembers class * extends android.webkit.webViewClient {
public void *(android.webkit.WebView, java.lang.String, android.graphics.Bitmap);
public boolean *(android.webkit.WebView, java.lang.String);
}
-keepclassmembers class * extends android.webkit.webViewClient {
public void *(android.webkit.webView, jav.lang.String);
}
# 移除Log类打印各个等级日志的代码,打正式包的时候可以做为禁log使用,这里可以作为禁止log打印的功能使用
# 记得proguard-android.txt中一定不要加-dontoptimize才起作用
# 另外的一种实现方案是通过BuildConfig.DEBUG的变量来控制
-assumenosideeffects class android.util.Log {
public static int v(...);
public static int i(...);
public static int w(...);
public static int d(...);
public static int e(...);
}
#############################################
#
# 项目中特殊处理部分
#
#############################################
#-----------处理反射类---------------
#-keepattributes *Annotation*
#-----------处理js交互---------------
#-----------处理实体类(不参与混淆的类)---------------
# 在开发的时候我们可以将所有的实体类放在一个包内,这样我们写一次混淆就行了。
#例子
# 不参与混淆的包
#-keep class com.juli.blecardsdk.libaries.ble.**{ *; }
# 不参与混淆的类
#-keep public class * extends com.juli.blecardsdk.libaries.command_mode.base.BaseResponseCodeAnalyser
#-keep class scj.jl.com.serialportlibrary.JLSerialportSDK
#-keep class scj.jl.com.serialportlibrary.serialportpro.**{ *; }
#-keep class scj.jl.com.serialportlibrary.scjpower.**{ *; }
#-keep class scj.jl.com.serialportlibrary.**{ *; }
#-keep class jl.**{ *; }
## protobuf(jpush依赖)
# -dontwarn com.google.**
#-keep class com.google.** {*;}
#-keep class com.google.jlprotobuf.InvalidProtocolBufferException.**
#
#-keep class com.test.blecardsdk.libaries.**{ *; }
#-keep public class * extends java.lang.Throwable {*;}
#-keep public class * extends java.lang.Exception {*;}
#-keep class com.google.protobuf.micro.** { *; }
#-keep class com.google.protobuf.** { *; }
#-----------处理第三方依赖库---------
## 百度地图(jar包换成自己的版本,记得签名要匹配)
##-libraryjars libs/BaiduLBS_Android.jar
#-keep class com.baidu.** {*;}
#-keep class vi.com.** {*;}
#-keep class com.sinovoice.** {*;}
#-keep class pvi.com.** {*;}
#-dontwarn com.baidu.**
#-dontwarn vi.com.**
#-dontwarn pvi.com.**
##-keep class com.baidu.** {*;}
##-keep class vi.com.** {*;}
##-dontwarn com.baidu.**
#
## ButterKnife
#-keep public class * implements butterknife.Unbinder {
# public <init>(**, android.view.View);
#}
#-keep class butterknife.*
#-keepclasseswithmembernames class * {
# @butterknife.* <methods>;
#}
#-keepclasseswithmembernames class * {
# @butterknife.* <fields>;
#}
#
## Gson
#-keepattributes Signature
#-keepattributes *Annotation*
#-keep class sun.misc.Unsafe { *; }
#-keep class com.google.gson.stream.** { *; }
## 使用Gson时需要配置Gson的解析对象及变量都不混淆。不然Gson会找不到变量。
## 将下面替换成自己的实体类
#
## OkHttp
#-dontwarn okio.**
#-dontwarn okhttp3.**
#-dontwarn javax.annotation.Nullable
#-dontwarn javax.annotation.ParametersAreNonnullByDefault
#
## OkHttp3
#-dontwarn com.squareup.okhttp3.**
#-keep class com.squareup.okhttp3.** { *;}
#-dontwarn okio.**
## Okio
#-dontwarn com.squareup.**
#-dontwarn okio.**
#-keep public class org.codehaus.* { *; }
#-keep public class java.nio.* { *; }
#
## 微信支付
#-dontwarn com.tencent.mm.**
#-dontwarn com.tencent.wxop.stat.**
#-keep class com.tencent.mm.** {*;}
#-keep class com.tencent.wxop.stat.**{*;}
#
## 支付宝钱包
#-dontwarn com.alipay.**
#-dontwarn HttpUtils.HttpFetcher
#-dontwarn com.ta.utdid2.**
#-dontwarn com.ut.device.**
#-keep class com.alipay.android.app.IAlixPay{*;}
#-keep class com.alipay.android.app.IAlixPay$Stub{*;}
#-keep class com.alipay.android.app.IRemoteServiceCallback{*;}
#-keep class com.alipay.android.app.IRemoteServiceCallback$Stub{*;}
#-keep class com.alipay.sdk.app.PayTask{ public *;}
#-keep class com.alipay.sdk.app.AuthTask{ public *;}
#-keep class com.alipay.mobilesecuritysdk.*
#-keep class com.ut.*
#
## greeDAO
#-keepclassmembers class * extends org.greenrobot.greendao.AbstractDao {
#public static java.lang.String TABLENAME;
#}
#-keep class **$Properties
## If you do not use SQLCipher:
#-dontwarn org.greenrobot.greendao.database.**
## If you do not use Rx:
#-dontwarn rx.**
2.配置build.gradle文件如图
apply plugin: 'com.android.library'
android {
compileSdkVersion 27
defaultConfig {
minSdkVersion 15
targetSdkVersion 27
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
//gradle版本小于4.6的时候使用minifyEnabled 混淆
minifyEnabled true //混淆 todo-打jar包的时候变为true
zipAlignEnabled true // Zipalign优化
shrinkResources true // 移除无用的resource文件 Android 3.0以后不需要
// 前一部分代表系统默认的android程序的混淆文件,该文件已经包含了基本的混淆声明,// 后一个文件是自己的定义混淆文件
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro
//新版gradle的混淆
postprocessing {
removeUnusedCode false //删除未使用的代码
removeUnusedResources false //清除未使用的资源
obfuscate false //是否混淆
optimizeCode false //是否优化
proguardFile 'proguard-rules.pro'
}
}
}
sourceSets{
main{
jniLibs.srcDirs=['Libs']
}
}
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
// compileOnly files('libs/sdk.jar')//compileOnly表示只参与编译,不参与打包
implementation 'com.android.support:appcompat-v7:27.1.1'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation project(':utillibrary')
// implementation files('libs/JlScjLib-1.0-v5-2020_04_26--11:35.jar')
}
//-------------------------------------------打jar包--------------------------------------------//
def releaseTime() {
return new Date().format("yyyy_MM_dd--HH:mm")
}
task makeJar(type: Jar ) {
def name = project.name
def fileName = name+".${android.defaultConfig.versionName}-${releaseTime()}"
archivesBaseName = fileName
//编译完工程后module中的Java文件已经生成了包含class 的classes.jar包
from(project.zipTree('build/intermediates/packaged-classes/release/classes.jar'))//新gradle的jar存放路径
from(project.zipTree('build/intermediates/build/release/classes.jar')) //gradle 4.6以前的jar存放路径
//将第三方jar包打包到将要打包的jar包中
// from(project.zipTree("build/intermediates/packaged-classes/release/libs/要包含的第三方jar"))//在添加混淆第三方jar包构建时可能找不到release文件夹
// from(project.zipTree("libs/要包含的第三方jar或者其他资源文件"))//确保一定找到资源文件
// from fileTree(dir: "libs", include: "**/*.so") //将libs文件下的.so库打包的jar包中
// from fileTree(dir: 'src/main',includes: ['assets/**'])//将assets目录打入jar包
destinationDir = file('build/libs')
}
makeJar.dependsOn( build)
//-------------------------------------------打aar包--------------------------------------------//
task modefyAarName(type: Copy) {
def name = project.name
def fileName = name+".${android.defaultConfig.versionName}-${releaseTime()}.aar"
from("build/outputs/aar/"+project.name+"-release.aar")
into("build/libs")
rename(project.name+"-release.aar", fileName)
}
//modefyAarName.dependsOn(build)
task modefyJarName(type: Copy){
def name = project.name
def fileName = name+"-server--${android.defaultConfig.versionName}-${releaseTime()}.jar"
from("build/intermediates/packaged-classes/release/classes.jar")
into("build/libs")
rename("classes.jar",fileName)
}
//modefyJarName.dependsOn(build)
其中,release 部分配置了开启混淆,保证打包 release 时会进行混淆。debug 不进行混淆,否则无法调试。生成的jar包在路径build/bin/下,jar包名字是fileName的名字,这个jar包其实是将build/intermediates/bundles/release/下的classes.jar包修改了名字然后拷贝到了build/bin 下。
3点击右上角的Gradle选择你的Mudule点击,然后点击other,找到make.jar双击。如图
之后查看你的build/bin文件夹如果有jar包说明执行成功。
参考资料点击打开链接。