Android

Android打包apk瘦身优化

2023-03-24  本文已影响0人  android_seven
瘦身优化.png

为什么要对apk包体积进行优化?

体积越大,下载流量大,安装时间长,在竞品中低体积包更容易获取用户;ROM厂商会有一些内置的应用,由于内存较小,需要优化,减少内存占用。

如何优化?

首先切图上,可以使用720p(xhdpi)来适配,其次,在图片使用上,一些小图标尽量使用svg(体积最小,如果你需要支持5.0以下,建议一套png图标搞定),如果对于非透明的大图,jpg将会比png的大小有显著的优势, 在启动页,活动页等之类的大图展示区采用jpg将是非常明智的选择,其它使用png就可以了,TinyPNG工具只支持上传PNG图片到官网上压缩,然后下载保存,在保持alpha通道的情况下对PNG的压缩可以达到1/3之内,而且用肉眼基本上分辨不出压缩的损失.
Tinypng的官方网站。其他方案这个文章可以参考下:Android开发小技巧,3种类型图片带你降低包体积

AndroidStudio提供了一键移除未使用资源的工具,refractor->remove unused resources,但是不建议使用,因为如果资源是动态获取的,也会认为未被使用而被物理移除。如果要用,通过Lint工具,、Code->Analyze->Run inspection by name->unused resource删除。

使用shrinkResources,他不会删除源文件,只会对打包出来的apk做优化,它需要和代码混淆一起开启,因为只有先开启代码混淆(压缩),才会知道资源是否引用,才会对资源进行剔除。非严苛模式下,不会剔除Resources.getIdentifier() 动态引用的资源,严苛模式下会剔除

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"
    tools:discard="@layout/shrink1"
    tools:keep="@layout/shrink"
    tools:shrinkMode="safe"/>
    <!--discard:做严格检查-->
    <!--keep :不做严格检查-->
    <!--shrinkMode="strict" :该模式只保留在代码或者资源文件中明确引用的资源-->
    <!--shrinkMode="safe" :该模式会保留所有明确引用的资源以及可能被 Resources.getIdentifier() 动态引用的资源-->

shrink-code官方文档

大部分应用其实并不需要支持几十种语言的国际化支持。还好强大的gradle支持语言的配置

android {
    defaultConfig {
        resConfigs 'en','zh-rCN'
    }
}

分包:同时会打两个包

    splits {
        abi {
            enable true
            reset()
            include  'armeabi-v7a',"arm64-v8a"
            universalApk false
        }
    }

只保留armeabi-v7a

  ndk {
            abiFilters 'armeabi-v7a'
        }

使用代码混淆,优化代码压缩

buildTypes {
        release {
//            源代码混淆 true
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }

#(1)dump.txt —- 说明APK中所有类文件的内部结构
#(2)mapping.txt —- 提供原始与混淆过的类、方法和字段名称之间的转换
#(3)seeds.txt —- 列出未进行混淆的类和成员
#(4)usage.txt —- 列出从APK移除的代码
#这些文件保存在/build/outputs/mapping/release目录下。
#解码混淆过的堆叠追踪
#使用混淆后,一定要保存好mapping文件,程序csh时通过脚本进行解码。
#retrace工具位于/tools/proguard/目录中,解码命令为:
#
# retrace.bat|retrace.sh [-verbose] mapping.txt [<stacktrace_file>]



# 指定代码的压缩级别
-optimizationpasses 5
# # 忽略警告,避免打包时某些警告出现(慎用)
-ignorewarnings
# 混淆时不生成大小写混合的类名
-dontusemixedcaseclassnames
# 混淆第三方jar
-dontskipnonpubliclibraryclasses
# 不预先验证已处理的类文件
-dontpreverify
# 混淆运行出现异常时打印日志在控制台
-verbose
# 混淆时所采用的算法
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*

# 保持某个包的类不被混淆
-keep class com.umeng.** { *; }

# 保持自定义的类不被混淆
#-keep class 类名

# 保留继承了哪些类的类不被混淆
-keep public class * extends android.app.Service
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.preference.Preference
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.content.BroadcastReceiver
#-keep public class com.android.vending.licensing.ILicensingService

# 保留实现了Serializable接口方法的类不被混淆
-keepclassmembers class * implements java.io.Serializable {*;}

# 保持实现Parcelable接口方法的类不被混淆
-keepclassmembers class * implements android.os.Parcelable

# 保持自定义控件类不被混淆
-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet);
}

# 保持 native 方法不被混淆
-keepclasseswithmembernames class * {
    native <methods>;
}

# 保持自定义控件类不被混淆
-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet);
    public <init>(android.content.Context, android.util.AttributeSet, int);
}

# 保持枚举 enum 类不被混淆
-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

#butterKnife
-keep class butterknife.** { *; }
-dontwarn butterknife.internal.**
-keep class **$$ViewBinder { *; }
-keepclasseswithmembernames class * {
   @butterknife.* <fields>;
}
-keepclasseswithmembernames class * {
   @butterknife.* <methods>;
}
#Gson
# removes such information by default, so configure it to keep all of it.
-keepattributes Signature
# Gson specific classes
-keep class sun.misc.Unsafe { *; }
-keep class com.google.gson.stream.** { *; }
# Application classes that will be serialized/deserialized over Gson
-keep class com.google.gson.examples.android.model.** { *; }
-keep class com.google.gson.** { *;}
#这句非常重要,主要是滤掉 com.demo.demo.bean包下的所有.class文件不进行混淆编译,com.demo.demo是你的包名
-keep class com.demo.demo.bean.** {*;}

#slideMenu
-dontwarn com.jeremyfeinstein.slidingmenu.lib.**
-keep class com.jeremyfeinstein.slidingmenu.lib.**{*;}

总结

apk瘦身主要是从图片文件、代码混淆(压缩)、无用资源剔除优化、so库这几个方面来优化。

上一篇 下一篇

猜你喜欢

热点阅读