Apk 简单瘦身, 混淆规则,及加固的使用

1.删除无用的语言资源

在语言的配置上,只保留需要用到的语言,目前项目只保留中文即可,有些项目可能保留英文

defaultConfig{

        resConfigs "zh"

}

2.进行删除无用的图片资源,及混淆开启

 minifyEnabled true   默认为false 当为true的时候,进行代码混淆

    实验发现,开启后方法数从13w缩减到10w,效果还是比较显著的

shrinkResources true 1. 去除项目中无用资源    2. 去除项目中临时展示的图片

   buildTypes {

              debug {

                           minifyEnabled true

                             shrinkResources true

        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'

     }

 }

3.图片压缩

使用tinypng进行图片压缩,可以反复压缩,但是相应解压缩时间变长,带来一些性能影响,对用户体验不会造成影响。

⚠️启动页图片最好不要进行压缩,启动时间会变长

tinypng批量处理

1)安装pip https://pypi.org/project/pip/

curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py

sudo python get-pip.py

2)安装tinify

sudo pip install --upgrade tinify

3)生成tinypng key 每个月免费500张

---------------------


类/方法混淆

1⃣️配置proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro',此处采用默认的混淆文本,也可以自定义。使用keep保持不需要进行混淆的文件。

2⃣️配置优化的proguard: proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' (不太稳定,比如在Dalvik模拟器上可能发生闪退,不推荐)

其他图片格式

1⃣️jpg 对于启动图等很大的图片,可以考虑用jpg格式代替png

2⃣️webp格式

支持4.0+设备,4.0以下不显示图片

在4.0 ~ 4.2.1的设备上无法显示带有透明度的webp,比如,把png转成webp则无法显示,但是如果把png先转成jpg再转成webp则能正常显示了,但会丢失透明度。

3⃣️矢量图svg

优点:矢量图由点和线组成,放再大也可以保持清晰度,占用空间小,不会出现锯齿

缺点:只支持5.0+系统,与位图相比多一层计算,消耗更多性能

⚠️android系统对png图片的解析时间是最短的,更换图片格式的时候要考虑一下性能损失

混淆规则

#代码混淆压缩比,在0~7之间,默认为5,一般不做修改

-optimizationpasses 5


#混合时不使用大小写混合,混合后的类名为小写

-dontusemixedcaseclassnames


#指定不去忽略非公共库的类

-dontskipnonpubliclibraryclasses


#这句话能够使我们的项目混淆后产生映射文件

#包含有类名->混淆后类名的映射关系

-verbose


#指定不去忽略非公共库的类成员

-dontskipnonpubliclibraryclassmembers


#不做预校验,preverify是proguard的四个步骤之一,Android不需要preverify,去掉这一步能够加快混淆速度。

-dontpreverify


#保留Annotation不混淆

-keepattributes *Annotation*,InnerClasses


#避免混淆泛型

-keepattributes Signature


#抛出异常时保留代码行号

-keepattributes SourceFile,LineNumberTable


#指定混淆是采用的算法,后面的参数是一个过滤器

#这个过滤器是谷歌推荐的算法,一般不做更改

-optimizations !code/simplification/cast,!field/*,!class/merging/*



#############################################

#

# 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



#保留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序列化的类不被混淆

-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);

}


# 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(...);

#}

1

2

142

上面这些基本不用动,描述的也很清晰了,我们主要解决的是下列中的部分–项目中特殊处理部分。


#############################################

#

#项目中特殊处理部分

#

#############################################


#-----------处理反射类---------------




#-----------处理js交互---------------




#-----------处理实体类---------------

#在开发的时候我们可以将所有的实体类放在一个包内,这样我们写一次混淆就行了。

#-keep public class com.ljd.example.entity.** {

#    public void set*(***);

#    public *** get*();

#    public *** is*();

#}



#-----------处理第三方依赖库---------

1

24

说一下第三方库,你需要确认你的项目中libs下引用了哪些地方的jar包,还有就是gradle中添加了哪些第三方库的依赖。

下面介绍一些常用的第三方混淆配置,仅供参考


# AndroidEventBus

-keep class org.simple.** { *; }

-keep interface org.simple.** { *; }

-keepclassmembers class * {

    @org.simple.eventbus.Subscriber <methods>;

}


#百度地图(jar包换成自己的版本,记得签名要匹配)

-libraryjars libs/baidumapapi_v2_1_3.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.**


# Bugly

-dontwarn com.tencent.bugly.**

-keep class com.tencent.bugly.** {*;}


# ButterKnife

-keep class butterknife.** { *; }

-dontwarn butterknife.internal.**

-keep class **$$ViewBinder { *; }

-keepclasseswithmembernames class * {

    @butterknife.* <fields>;

}

-keepclasseswithmembernames class * {

    @butterknife.* <methods>;

}


# EventBus

-keepattributes *Annotation*

-keepclassmembers class ** {

    @org.greenrobot.eventbus.Subscribe <methods>;

}

-keep enum org.greenrobot.eventbus.ThreadMode { *; }


# Facebook

-keep class com.facebook.** {*;}

-keep interface com.facebook.** {*;}

-keep enum com.facebook.** {*;}


# FastJson

-dontwarn com.alibaba.fastjson.**

-keep class com.alibaba.fastjson.** { *; }

-keepattributes Signature

-keepattributes *Annotation*


# Fresco

-keep class com.facebook.fresco.** {*;}

-keep interface com.facebook.fresco.** {*;}

-keep enum com.facebook.fresco.** {*;}


#高德相关依赖

#集合包:3D地图3.3.2 导航1.8.0 定位2.5.0

-dontwarn com.amap.api.**

-dontwarn com.autonavi.**

-keep class com.amap.api.**{*;}

-keep class com.autonavi.**{*;}

#地图服务

-dontwarn com.amap.api.services.**

-keep class com.map.api.services.** {*;}

# 3D地图

-dontwarn com.amap.api.mapcore.**

-dontwarn com.amap.api.maps.**

-dontwarn com.autonavi.amap.mapcore.**

-keep class com.amap.api.mapcore.**{*;}

-keep class com.amap.api.maps.**{*;}

-keep class com.autonavi.amap.mapcore.**{*;}

#定位

-dontwarn com.amap.api.location.**

-dontwarn com.aps.**

-keep class com.amap.api.location.**{*;}

-keep class com.aps.**{*;}

#导航

-dontwarn com.amap.api.navi.**

-dontwarn com.autonavi.**

-keep class com.amap.api.navi.** {*;}

-keep class com.autonavi.** {*;}


# Glide

-keep public class * implements com.bumptech.glide.module.GlideModule

-keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** {

  **[] $VALUES;

  public *;

}


# Gson

-keepattributes Signature-keepattributes *Annotation*

-keep class sun.misc.Unsafe { *; }

-keep class com.google.gson.stream.** { *; }

#使用Gson时需要配置Gson的解析对象及变量都不混淆。不然Gson会找不到变量。

#将下面替换成自己的实体类

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


# Jackson

-dontwarn org.codehaus.jackson.**

-dontwarn com.fasterxml.jackson.databind.**

-keep class org.codehaus.jackson.** { *;}

-keep class com.fasterxml.jackson.** { *; }


#极光推送

-dontoptimize

-dontpreverify

-dontwarn cn.jpush.**

-keep class cn.jpush.** { *; }


# 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.* { *; }


# OrmLite

-keepattributes *DatabaseField*

-keepattributes *DatabaseTable*

-keepattributes *SerializedName*  

-keep class com.j256.**

-keepclassmembers class com.j256.** { *; }

-keep enum com.j256.**

-keepclassmembers enum com.j256.** { *; }

-keep interface com.j256.**

-keepclassmembers interface com.j256.** { *; }


# Realm

-keep class io.realm.annotations.RealmModule

-keep @io.realm.annotations.RealmModule class *

-keep class io.realm.internal.Keep

-keep @io.realm.internal.Keep class * { *; }

-dontwarn javax.**

-dontwarn io.realm.**


# Retrofit

-dontwarn retrofit2.**

-keep class retrofit2.** { *; }

-keepattributes Signature

-keepattributes Exceptions


# Retrolambda

-dontwarn java.lang.invoke.*


# RxJava RxAndroid

-dontwarn sun.misc.**

-keepclassmembers class rx.internal.util.unsafe.*ArrayQueue*Field* {

    long producerIndex;

    long consumerIndex;

}

-keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueProducerNodeRef {

    rx.internal.util.atomic.LinkedQueueNode producerNode;

}

-keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueConsumerNodeRef {

    rx.internal.util.atomic.LinkedQueueNode consumerNode;

}


#微信支付

-dontwarn com.tencent.mm.**

-dontwarn com.tencent.wxop.stat.**

-keep class com.tencent.mm.** {*;}

-keep class com.tencent.wxop.stat.**{*;}


#信鸽

-keep public class * extends android.app.Service

-keep public class * extends android.content.BroadcastReceiver

-keep class com.tencent.android.tpush.**  {* ;}

-keep class com.tencent.mid.**  {* ;}

-keepattributes *Annotation*


#新浪微博

-keep class com.sina.weibo.sdk.* { *; }  

-keep class android.support.v4.* { *; }  

-keep class com.tencent.* { *; }  

-keep class com.baidu.* { *; }  

-keep class lombok.ast.ecj.* { *; }  

-dontwarn android.support.v4.**  

-dontwarn com.tencent.**s  

-dontwarn com.baidu.**  


#讯飞语音

-dontwarn com.iflytek.**

-keep class com.iflytek.** {*;}


#银联

-dontwarn com.unionpay.**

-keep class com.unionpay.** { *; }


#友盟统计分析

-keepclassmembers class * { public <init>(org.json.JSONObject); }

-keepclassmembers enum com.umeng.analytics.** {

    public static **[] values();

    public static ** valueOf(java.lang.String);

}


#友盟自动更新

-keepclassmembers class * { public <init>(org.json.JSONObject); }

-keep public class cn.irains.parking.cloud.pub.R$*{ public static final int *; }

-keep public class * extends com.umeng.**

-keep class com.umeng.** { *; }


#支付宝钱包

-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.*


加固方面  

目前本人使用的是360加固助手,自己可以去搜索官网下载,进行注册

在Android studio  gradle 中去 配置自己的签名


signingConfigs {

release {

        storeFile file('key0') // 打包时候的别名

        storePassword"000000"  // 打包的密码

        keyAlias"D:/SmallPrincess_WorkSpace/Big_WanAndroid/app/asd.jks" //路径改成自己的jks生成的位置

        keyPassword"000000"   // 打包的密码

    }

}

然后在 以下配置中配置 signingConfig signingConfigs.release   release必须跟签名配置的那个名字一致

buildTypes {

release {

        shrinkResourcestrue

        minifyEnabledtrue

        proguardFiles getDefaultProguardFile('proguard-android.txt'),'proguard-rules.pro'

        signingConfig signingConfigs.release

    }

}

配置完成之后去  Android  studio中去打包

打包完成之后去 360加固助手中  添加apk进行加固即刻,需要注意的一点是 同样配置签名跟依赖的签名要保持一致,即可。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,711评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,932评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,770评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,799评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,697评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,069评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,535评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,200评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,353评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,290评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,331评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,020评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,610评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,694评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,927评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,330评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,904评论 2 341

推荐阅读更多精彩内容