天问

  • Blog
  • 热修复与动态加载
  • python爬虫
  • 专栏
    • 热修复与动态加载
    • NDK开发
    • 设计模式与架构
    • React Native
  • 好文转载
    • 计算机技术
    • 投资理财
    • 摄影与拍照技巧
  • 投稿
  • 关于本站及隐私政策
  • Github
StevenQ
为今天工作,为明天投资,为未来孵化一些东西!
  1. 首页
  2. 计算机技术
  3. 安卓开发
  4. 正文

使用Android Studio导出release的aar并进行混淆

2018年4月29日 2296点热度 4人点赞 0条评论

导出release的aar

通常情况aar是作为一个libary模块供主工程引用的,如果我们要导出aar也很容易,选中libary模块,然后点击AS上方菜单栏的build->make module,如图所示:

然后就会在libary模块的build/ouputs/aar/目录下生成编译好的aar,但是这样直接Make Module编译出来的aar默认是debug版本的,如果想要编译出release版本的aar需要在AS左下角的Build Variants中选择编译类型为release,如下所示:

然后Make Module之后outputs目录下生成的aar就是release版本的aar了,如图所示:

对aar进行混淆

对于AS而言,混淆jar/aar非常方便,只需要在我们创建的aar/jar 模块的build.gradle中打开混淆规则即可,如下所示:

buildTypes {
    release {
        minifyEnabled true//打开releae模式混淆
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
    debug{
        minifyEnabled true//打开debug模式混淆
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}

然后在模块的proguard-rules.pro文件中进行混淆规则配置,然后选中该模块,执行AS的build->make module,这样编译出来的jar/aar就是应用了proguard-rules.pro文件中混淆规则的jar/aar了。

混淆基本语法和规则

proguard混淆的基本作用是压缩,优化和混淆,当在module的build.gradle中把minifyEnabled开关置为true时则这3个功能默认开启,可分别通过-dontshrink关闭压缩,-dontoptimize关闭优化,-dontobfuscate关闭混淆。其中混淆能够将类和类成员进行随机化命令,增大反编译查看难度,是我们使用proguard混淆的主要原因。但是有时候某些类和函数我们不希望被混淆,比如在开发SDK的时候提供给接入者的对外的接口我们是不希望混淆的,这个时候我们需要配置proguard规则通过类似keep这样的命令来保持某些类不被混淆。

-keep和-keep {*;}保持类名称和成员不被混淆

在保持类不被混淆的命令中,最基本的就是-keep命令,该命令用来保持某个类类名不被混淆,如下是保持pkg包名下的类X不被混淆

-keep class com.example.pkg.X

如果我们希望整个pkg包名下的类名都不被混淆而不是单个类X的时候需要使用通配符*来表示,如下时表示保持pkg包名下的所有类的类名不被混淆:

-keep class com.example.pkg.*

但是一颗星的通配符只会保持该包名下的所有类名不被混淆,不包括该包名下子包名中的类,如果我们希望把该包名及其所有子包名下的类名都保持不混淆则需要使用2颗星的通配符**,如下表示保持pkg包名及其所有子包名下的类名称都保持不混淆:

-keep class com.example.pkg.**

如果要保持内部类不被混淆需要使用$,比如如下示例表示保持类X的内部类Y名称不被混淆:

-keep class com.example.pkg.X$Y

但是keep命令只会保持类名不被混淆,类里头的内容如域,函数还是会被混淆。如果希望保持类名和类中的域,函数不被混淆则需要使用keep {*;}命令了。如下是表示不混淆类X名称和类X中的所有内容:

-keep class com.example.pkg.X{*;}

同样的该命令也可以使用通配符,比如如下表示不混淆pkg包名下的所有类名称和类中的内容:

-keep class com.example.pkg.*{*;}

有些时候我们可能仅仅需要保持函数或域不被混淆,这个时候我们可以使用<init>;来表示所有构造器,<fields>表示所有域,<methods>;表示所有方法,而且可以在其前面加上public,private,native等这样的修饰符来表示特定特征的域/函数,比如如下示例表示保持类X的内部类Y的名称及类Y中所有public函数不被混淆

-keep class com.example.pkg.X$Y{
public <methods>;
}

这些规则同样适用于包名通配符*命令,比如如下示例表示保持pkg包名下所有类名称和类中所有public函数不被混淆:

-keep class com.example.pkg.*{
public <methods>;
}

-keepclassmembers保持类成员不被混淆

某些情况下可能我们不在乎类名是否被混淆,我们仅仅在乎类中的方法名称不被混淆,这个时候需要使用-keepclassmembers命令,该命令用来混淆类名,但是不混淆类中的某个成员,与keep命令唯一的区别是keep命令会保持类名称而keepclassmembers命令不会保持类名称,其余的keep命令中的通配符*,{*;}等所有语法都同样适用于该命令,如下是一个对比示例:

-keep class com.example.pkg.X{ #类X的名称不会被混淆
public <fields>; #所有的public的域不被混淆
public <methods>;#所有的public的方法不被混淆
}
-keepclassmembers class com.example.pkg.X{#类X的名称会被混淆
public <fields>; #所有的public的域不被混淆
public <methods>;#所有的public的方法不被混淆
}

关于保持某些case不被混淆的指令还有很多,但是基本上这2个就足够解决绝大多数我们不希望混淆的情况了。

常用的混淆规则示例

  • 不混淆某个类
-keep class com.example.pkg.X
  • 不混淆某个包及其子包下所有的类
-keep class com.example.pkg.**{*;}
  • 不混淆某个类的子类
-keep public class * extends com.example.pkg.X { *; }
  • 不混淆某个类特定的方法
-keep public class * extends com.example.pkg.X {
    public void test(java.lang.String);
}
  • 常见的通用的一些混淆配置
-dontshrink #不压缩
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/* #混淆时采用的算法,建议不要修改
-optimizationpasses 5 #指定压缩级别
-dontusemixedcaseclassnames#是否使用大小写混合
-keepattributes *Annotation*
-dontpreverify
-verbose# 混淆时是否生成mapping文件
-dontwarn android.support.v4.*
-ignorewarnings
  • 去除日志(在未开启-dontoptimize选项前提下)
-assumenosideeffects class android.util.Log {
    public static *** d(...);
    public static *** e(...);
    public static *** i(...);
    public static *** w(...);
}

在主工程中使用aar

在主工程中使用aar首先把aar包放到主工程的libs目录下,然后在主工程的build.gradle文件的dependencies中添加依赖:

compile(name: 'quickpass_libary-release', ext: 'aar')

其中name的值即使放到libs目录下的aar的名称,然后在app的build.gradle的android节点下添加如下内容即可:

repositories {
    flatDir {
        dirs 'libs'
    }
}

 

本作品采用 知识共享署名 4.0 国际许可协议 进行许可
标签: AS技巧 proguard 混淆
最后更新:2018年5月1日

天问

追梦追自由,穷则独善其身,达则兼济天下

打赏 点赞
< 上一篇
下一篇 >

COPYRIGHT © 2022 天问 ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang