由于最近作者刚开发完一个SDK项目,所有现在整理一下在此期间碰到的坑,希望别人在做SDK的时候不用再重新踩一遍坑了。好了废话不多说,现在开始
一、前期准备
1.sdk说白了就是把一些方法函数封装起来,然后打成一个Jar包给第三方开发者来调用,以减少第三方开发者工作量和一些重复的内容
2.因为jar包有的逻辑算法是比较隐私和重要的,所以Jar一定是要做混淆的。
如果有人用过一些开源的项目库或者Jar的时候有可能会注意到,Jar混淆一些代码,
如:使用fastjson.jar
一款自动解析Json的一个Jar包,该Jar要添加的混淆是这样的
-dontwarn com.alibaba.fastjson.**
-keep class com.alibaba.fastjson.** { *; }
-keep class com.alibaba.fastjson.TypeReference.** { *; }
3.知道了有上面混淆的这个点之后,所以在开发之前要把包名给设计好,
4.剩下的就是进行封装代码了,根据各自业务自行封这个就不用多说了。
二、代码混淆设置
因为我们项目是用Android Studio进行开发的,所以在此只针对于使用Android Studio的开发者
以下是build.gradle 重要混淆代码
task buildJar(dependsOn: ['compileReleaseJavaWithJavac'], type: Jar) {
appendix = "demo"
baseName = "androidJar"
version = "1.0.0"
classifier = "release"
//后缀名
extension = "jar"
//最终的 Jar 包名,如果没设置,默认为 [baseName]-[appendix]-[version]-[classifier].[extension]
archiveName = "****.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 "com/app/**/*.class"
include "tv/danmaku/ijk/**/*.class"
//注: exclude include 支持可变长参数
}
task proguardJar(dependsOn: ['buildJar'], type: ProGuardTask) {
delete(project.buildDir.absolutePath)
def mappingOutputDir = new File(project.buildDir.absolutePath + "/outputs/mapping/release/")
if (!mappingOutputDir.exists()) {
mappingOutputDir.mkdirs()
}
def mappingOutputFile = new File(mappingOutputDir, "mapping.txt")
mappingOutputFile.createNewFile()
//Android 默认的 proguard 文件
configuration android.getDefaultProguardFile('proguard-android.txt')
//manifest 注册的组件对应的 proguard 文件
configuration project.buildDir.absolutePath + "/intermediates/proguard-rules/release/aapt_rules.txt"
configuration 'proguard-rules.pro'
String inJar = buildJar.archivePath.getAbsolutePath()
//输入 jar
injars inJar
//输出 jar
outjars 'build/releaseLibs/****.jar' //inJar.substring(0, inJar.lastIndexOf('/')) + "/proguard-${buildJar.archiveName}"
//设置不删除未引用的资源(类,方法等)
dontshrink
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) {
//给 proguard 添加 runtime
libraryjars(runtimeJar)
}
}
三、在proguard-rules.pro 自行添加一些需要混淆包的代码
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in E:\androidDev\sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript inter
# class:
#-keepclassmembers class fqcn.of.javascript.inter.for.webview {
# public *;
#}
-optimizationpasses 5
-dontskipnonpubliclibraryclasses
-dontskipnonpubliclibraryclassmembers
-dontpreverify
-verbose
-ignorewarnings
-dontusemixedcaseclassnames # 是否使用大小写混合
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*,!code/allocation/variable
# 记录生成的日志数据,在mapping目录下
-printmapping build/outputs/mapping/release/mapping.txt
-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 com.android.vending.licensing.ILicensingService
-keep public class android.net.http.SslError
-dontwarn javax.annotation.**
-dontwarn android.app.**
-dontwarn android.support.**
-dontwarn android.view.**
-dontwarn android.widget.**
-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);
void set*(***);
*** get*();
}
-keepclasseswithmembernames class * {
native <methods>;
}
# Keep native methods
-keepclassmembers class * {
native <methods>;
}
-keepclassmembers class **.R$* {
public static <fields>;
}
-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.app.Activity {
public void *(android.view.View);
}
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
#==============用到注解相关混淆配置=================
-keepattributes Exceptions
-keepattributes InnerClasses
-keepattributes Signature
#-keepattributes Deprecated
#-keepattributes SourceFile
#-keepattributes LineNumberTable
#-keepattributes LocalVariable*Table
#-keepattributes Synthetic
-allowaccessmodification
-keepattributes *Annotation*
-renamesourcefileattribute SourceFile
-keepattributes SourceFile,LineNumberTable
-repackageclasses ''
#==============用到反射相关混淆配置=================
-keepattributes Signature
-keepattributes EnclosingMethod
#==================gson==========================
-dontwarn com.google.**
-keep class com.google.gson.** {*;}
#==================protobuf======================
-dontwarn com.google.**
-keep class com.google.protobuf.** {*;}
#fastjson.jar 的类路径 com.alibaba.fastjson
-dontwarn com.alibaba.fastjson.**
-keep class com.alibaba.fastjson.** { *; }
-keep class com.alibaba.fastjson.TypeReference.** { *; }
#httpmime.jar 的类路径 org.apache.http.entity.mime
-dontwarn org.apache.http.**
-keep class org.apache.http.** { *; }
#日志模块 slf4j 和 logback 配置
-keep class ch.qos.** { *; }
-keep class org.slf4j.** { *; }
#-keepattributes *Annotation*
-dontwarn ch.qos.logback.**
-dontwarn ch.qos.logback.core.net.*
-keep class ch.qos.logback.** { *; }
#项目里所有的module不需要混淆
-dontwarn com.demo.sdk.**
-keep class com.demo.sdk.** { *; }
-dontwarn tv.danmaku.ijk.**
-keep class tv.danmaku.ijk.** { *; }
-keepclasseswithmembers class tv.danmaku.ijk.media.player.IjkMediaPlayer {
<fields>;
<methods>;
}
-keep class * implements java.io.Serializable { *; }
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keepclassmembers class * {
public <init>(org.json.JSONObject);
}
#-dontwarn okio.**
#-keep class okio.** {*;}
#-dontwarn okhttp3.**
#-keep class okhttp3.** {*;}
-dontwarn javax.annotation.**
-dontwarn com.android.volley.toolbox.**