未优化前:14MB, DownloadSize:12.7Mb(在AS中打开apk会显示)
1:AS -> refactor -> remove unused resources
做这步之前建议现在本地保留一份副本,如果报错,源文件也更好找一些
Apk size:13.6Mb, DownloadSize:12.5Mb
2:使用lint检查(AS中Analyze -> Run Inspection by name -> 输入unused resources)
步骤1已覆盖,无明显变化
3.tiny png大图压缩处理(https://tinypng.com/)
该步骤本人仅对所有超过100kb的图片处理
4.webp压缩批处理(res目录下右键选择Convert to WebP ->75% quality有损压缩)
5.冗余代码删除、精简、相关类资源删除
6.开启Proguard-开启代码混淆
附上我的混淆配置文件内容吧,proguard-rulues.pro
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /Users/Chris/Library/Android/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:
#-optimizationpasses 5 # 指定代码的压缩级别
#-dontusemixedcaseclassnames # 是否使用大小写混合
#-dontpreverify # 混淆时是否做预校验
#-verbose # 混淆时是否记录日志
#-optimizations !code/simplification/arithmetic,!field/*,!class/merging/* # 混淆时所采用的算法
#
#
#-libraryjars libs/pgyer_sdk_x.x.jar
#-dontwarn com.pgyersdk.**
#-keep class com.pgyersdk.** { *; }
# 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 *;
#}
#===================android=======================
-dontwarn
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
-keep public class * extends android.app.Fragment
-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 * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService
-dontwarn android.support.**
-keep class android.support.** { *; }
-keep class com.yto.camel.adapter.MyBaseAdapter {*;}
-keepclasseswithmembernames class * {
native <methods>;
}
-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 *;
}
#===================BaiduLBS======================
-keep class com.baidu.** {*;}
-keep class vi.com.** {*;}
-dontwarn com.baidu.**
#==================JPush==========================
-dontoptimize
-dontpreverify
-dontwarn cn.jpush.**
-keep class cn.jpush.** { *; }
#==================gson==========================
-dontwarn com.google.**
-keep class com.google.gson.** {*;}
#==================protobuf======================
-dontwarn com.google.**
-keep class com.google.protobuf.** {*;}
#================picasso==========================
-dontwarn com.squareup.okhttp.**
#==================litepal=======================
-keep class org.litepal.** { *; }
#==================fastjson=======================
-dontwarn com.alibaba.fastjson.**
-keep class com.alibaba.fastjson.** { *; }
-keepattributes Signature #避免混淆泛型
-keepattributes *Annotation #不混淆注释
-keepattributes InnerClasses #不混淆内部类
#===================pgy===================
#-libraryjars libs/pgyer_sdk_2.2.2.jar
-dontwarn com.pgyersdk.**
-keep class com.pgyersdk.** { *; }
#==================eventbus===============
-keep class org.simple.eventbus.** {*;}
-keepclassmembers class ** {
public void onEvent*(**);
void onEvent*(**);
void onClick*(**);
}
#==================xUtils=================
#-libraryjars libs/xUtils-2.6.14.jar
-keep class com.lidroid.** { *; }
-keep class * extends java.lang.annotation.Annotation { *; }
-keep class org.xutils.** {*;}
-keepattributes *Annotation*
-keep public interface org.xutils.** {*;}
-dontwarn java.lang.annotation.Annotation
-keep class com.demo.bean.** { *; }
-keepattributes *Annotation*
-keep @**annotation** class * {*;}
-dontwarn com.qiyukf.**
-keep class com.qiyukf.** {*;}
7.res/raw目录下新建keep.xml,开启严格模式资源压缩
格式如下:
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"
tools:shrinkMode="strict" />
8.资源混淆及7zip极限压缩(使用的是微信的开源方案)
首先,附上我的gradle配置,在app同目录下新建一个and_res_guard.gradle文件
apply plugin: 'AndResGuard'
andResGuard {
// mappingFile = file("./resource_mapping.txt")
mappingFile = null
//Do NOT enable 7zip compression(use7zip) when you distribute your APP on Google
//Play. It'll prevent the file-by-file patch when updating your APP.
use7zip = true
useSign = true
// it will keep the origin path of your resources when it's true
keepRoot = false
// 设置这个值,会把arsc name列混淆成相同的名字,减少string常量池的大小
fixedResName = "arg"
// 打开这个开关会合并所有哈希值相同的资源,但请不要过度依赖这个功能去除去冗余资源
mergeDuplicatedRes = true
whiteList = [
// your icon
//表情
"R.drawable.icon",
// for fabric
"R.string.com.crashlytics.*",
// for google-services
"R.string.google_app_id",
"R.string.gcm_defaultSenderId",
"R.string.default_web_client_id",
"R.string.ga_trackingId",
"R.string.firebase_database_url",
"R.string.google_api_key",
"R.string.google_crash_reporting_api_key"
]
compressFilePattern = [
"*.png",
"*.jpg",
"*.jpeg",
"*.gif",
//Do NOT add resource.asrc into compressFilePattern unless the app size is really matter //to you.
]
sevenzip {
artifact = 'com.tencent.mm:SevenZip:1.2.17'
//path = "/usr/local/bin/7za"
}
/**
* 可选: 如果不设置则会默认覆盖assemble输出的apk
**/
// finalApkBackupPath = "${project.rootDir}/final.apk"
/**
* 可选: 指定v1签名时生成jar文件的摘要算法
* 默认值为“SHA-1”
**/
// digestalg = "SHA-256"
}
在app目录下的build.gradle中添加
apply from: 'and_res_guard.gradle'
最后在附上我的buildTypes中的配置
buildTypes {
debug{
buildConfigField "boolean", "LOG_DEBUG", "false" //不显示log
shrinkResources true //去除无用资源
minifyEnabled true //开启混淆
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.debug
}
release {
// 不显示Log
buildConfigField "boolean", "LOG_DEBUG", "false"
//Zipalign优化
zipAlignEnabled true
// 移除无用的resource文件
shrinkResources true
//是否混淆
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
//签名
signingConfig signingConfigs.release
}
}
使用说明
在gradle:app->Tasks->andresguard->自己选择执行Debug包还是Release包
比如执行完resguardDebug脚本后,在app->build->outputs->apk->debug->AndResGuard_app-debug目录下,
app-debug_7zip_aligned_signed.apk就是最终对齐签名后的可发布包.
详细参考:https://github.com/shwenzhang/AndResGuard/blob/master/README.zh-cn.md
最终经过一系列处理后:包大小由14M优化缩减到9.3M,效果还是很不错的~