美文网首页Android
Android打包apk瘦身优化

Android打包apk瘦身优化

作者: android_seven | 来源:发表于2023-03-24 19:55 被阅读0次
    瘦身优化.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库这几个方面来优化。

    相关文章

      网友评论

        本文标题:Android打包apk瘦身优化

        本文链接:https://www.haomeiwen.com/subject/zbovrdtx.html