1.利用Android Studio导出jar包

利用Android Studio创建library module的过程就不描述了,下面直接进入正题

在library module的gradle文件中添加:

def SDK_BASENAME = "my_jar";//导出jar包的名称
    def SDK_VERSION = "_v1.0.0";//导出jar包版本
    def sdkDestinationPath = "build/outputs/jar/";//导出jar包路径
    def zipFile = file('build/intermediates/aar_main_jar/release/classes.jar')
    task deleteBuild(type: Delete) {
        delete sdkDestinationPath + SDK_BASENAME + SDK_VERSION + ".jar"
    }
    task makeJar(type: Jar) {
        from zipTree(zipFile)
        from fileTree(dir: 'src/main', includes: ['assets/**']) // 打包assets目录下的所有文件

        baseName = SDK_BASENAME + SDK_VERSION
        destinationDir = file(sdkDestinationPath)
    }
    makeJar.dependsOn(deleteBuild, build)

注意 def zipFile = file('build/intermediates/aar_main_jar/release/classes.jar'),这个classes.jar文件的路径根据Android Studio的版本不同,路径也不一样,这个需要自行查找。

然后在Android Studio工具Terminal下输入gradlew makeJar即可导出jar 包,

其中,makeJar只是一个方法名,可以自行定义

完整的gradle文件如下:

 

android {
    compileSdkVersion 29
    buildToolsVersion "30.0.2"

    defaultConfig {
        minSdkVersion 16
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        consumerProguardFiles "consumer-rules.pro"
    }

    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }


    def SDK_BASENAME = "my_jar";
    def SDK_VERSION = "_v1.0.0";
    def sdkDestinationPath = "build/outputs/jar/";
    def zipFile = file('build/intermediates/aar_main_jar/release/classes.jar')
    task deleteBuild(type: Delete) {
        delete sdkDestinationPath + SDK_BASENAME + SDK_VERSION + ".jar"
    }
    task makeJar(type: Jar) {
        from zipTree(zipFile)
        from fileTree(dir: 'src/main', includes: ['assets/**']) // 打包assets目录下的所有文件

        baseName = SDK_BASENAME + SDK_VERSION
        destinationDir = file(sdkDestinationPath)
    }
    makeJar.dependsOn(deleteBuild, build)

}

2.导出混淆后的jar包

首先将minifyEnabled 设置为true

buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }

其次配置混淆文件:proguard-rules.pro

通用的混淆规则:

###########################以下是AndroidStudio自带的混淆配置协议###############################

# 表示混淆时不使用大小写混合类名
-dontusemixedcaseclassnames

# 表示不跳过library中的非public的类
-dontskipnonpubliclibraryclasses

# 打印混淆的详细信息
-verbose

# Optimization is turned off by default. Dex does not like code run
# through the ProGuard optimize and preverify steps (and performs some
# of these optimizations on its own).
-dontoptimize

# 表示不进行校验,这个校验作用 在java平台上的
-dontpreverify
# Note that if you want to enable optimization, you cannot just
# include optimization flags in your own project configuration file;
# instead you will need to point to the
# "proguard-android-optimize.txt" file instead of this one from your
# project.properties file.
#使用注解需要添加
-keepattributes *Annotation*
-keep public class com.google.vending.licensing.ILicensingService
-keep public class com.android.vending.licensing.ILicensingService

# For native methods, see http://proguard.sourceforge.net/manual/examples.html#native
#指定不混淆所有的JNI方法
-keepclasseswithmembernames class * {
    native <methods>;
}

# keep setters in Views so that animations can still work.
# see http://proguard.sourceforge.net/manual/examples.html#beans
#所有View的子类及其子类的get、set方法都不进行混淆
-keepclassmembers public class * extends android.view.View {
   void set*(***);
   *** get*();
}

# We want to keep methods in Activity that could be used in the XML attribute onClick
# 不混淆Activity中参数类型为View的所有方法
-keepclassmembers class * extends android.app.Activity {
   public void *(android.view.View);
}

# For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations
# 不混淆Enum类型的指定方法
-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

# 不混淆Parcelable和它的子类,还有Creator成员变量
-keepclassmembers class * implements android.os.Parcelable {
  public static final android.os.Parcelable$Creator CREATOR;
}

# 不混淆R类里及其所有内部static类中的所有static变量字段
-keepclassmembers class **.R$* {
    public static <fields>;
}

# The support library contains references to newer platform versions.
# Don't warn about those in case this app is linking against an older
# platform version.  We know about them, and they are safe.
# 不提示兼容库的错误警告
-dontwarn android.support.**

# Understand the @Keep support annotation.
-keep class android.support.annotation.Keep

-keep @android.support.annotation.Keep class * {*;}

-keepclasseswithmembers class * {
    @android.support.annotation.Keep <methods>;
}

-keepclasseswithmembers class * {
    @android.support.annotation.Keep <fields>;
}

-keepclasseswithmembers class * {
    @android.support.annotation.Keep <init>(...);
}


###########################以下是需要手动的混淆配置协议###############################



#代码迭代优化的次数,默认5
-optimizationpasses 5
#混淆时不会产生形形色色的类名
-dontusemixedcaseclassnames


#忽略警告
-ignorewarnings

然后再添加你不希望混淆的文件规则即可,比如添加一个


-keep class com.google.gson.**{*;} 则避免混淆gom.google.gson包下的所有文件


添加好之后,直接在Terminal中执行导出jar包指令 gradlew makeJar

 

3.混淆之后和其他jar包包名冲突:如com.a.a.a.a

可以参考:

默认情况下,混淆后的名字一般为a、b、c、d以及它们的组合,通过修改混淆规则,控制混淆后的文件命名规则,从根本上避免与其他包可能出现同名的问题。具体步骤是需要在混淆规则文件proguard-rules.pro中做如下设置:

-obfuscationdictionary filename.txt
-classobfuscationdictionary filename.txt
-packageobfuscationdictionary package_filename .txt

  • -obfuscationdictionary filename .txt:指定一个混淆类名、成员变量名、方法名的字典。
  • -classobfuscationdictionary filename .txt:指定一个混淆类名的字典,字典的格式
  • -packageobfuscationdictionary package_filename .txt:filename 指定一个混淆包名的字典

filename.txt是用来指定混淆后生成的名字的字典文件,字典文件中的空格,标点符号,重复的词,还有以’#'开头的行都会被忽略。需要注意的是添加了字典并不会显著提高混淆的效果,添加字典有两个作用:一是避免与其他包混淆后重名;二是更不利与阅读;

与proguard-rules.pro同级目录下。

android studio 提取方法 android studio如何导出文件_android

下面是一个字典的示例,仅供参考:

如果是指定-packageobfuscationdictionary,这份文件最好是做一下和自己项目特征相关的修改,避免包名重复

# 使用java中的关键字作字典:避免混淆后与其他包重名,而且混淆之后的代码更加不利于阅读
#
# This obfuscation dictionary contains reserved Java keywords. They can't
# be used in Java source files, but they can be used in compiled class files.
# Note that this hardly improves the obfuscation. Decent decompilers can
# automatically replace reserved keywords, and the effect can fairly simply be
# undone by obfuscating again with simpler names.
# Usage:
#     java -jar proguard.jar ..... -obfuscationdictionary filename.txt
#

do
if
for
int
new
try
byte
case
char
else
goto
long
this
void
break
catch
class
const
final
float
short
super
throw
while
double
import
native
public
return
static
switch
throws
boolean
default
extends
finally
package
private
abstract
continue
strictfp
volatile
interface
protected
transient
implements
instanceof
synchronized