当前位置: 首页>前端>正文

性能优化之APK减肥记

引言

? 有那么一句话 <u>“一百遮百丑,一胖毁所有”</u> ,这句话用在我们开发的应用程序上也不为过。为什么会这样说呢?

1.应用程序如果太大,用户下载耗时比较久,占用的流量也大 ,安装速度也就慢,这样用户很容易放弃使用;

2.这么胖的应用程序在运行过程中需要加载的资源和程序都很多,会导致加载速度慢,影响用户使用体验;

3.胖的应用也会在后续的项目维护中造成比较大的麻烦,例如:胖会引起比较多的疾病一样;

? 看来我们对自己开发的应用程序制定一个减肥方案是有必要的,但是在制定方案之前,我们就得像医生一样,对其的构成和胖的原因进行全面的掌握,然后才知道如何制定减肥方案。

1)先来了解一下应用程序的组成结构:

性能优化之APK减肥记,第1张
APK文件结构

assets目录: 用于存放需要打包到APK中的静态文件,不参与编译,仅拷贝,可以使用AssetManager来检索这些资源;

res目录: 包含未编译到resources.arsc文件中的资源,如:图片,音视频文件等;

resources.arsc: 包含已经编译的资源,如anim 、array、String 、color、raw、style、xml、attr、drawable、menu等等;

lib目录: 包含用于特定处理器软件层的编译的代码,也就是兼容不同平台的类库,常见的有:armeabi,armeabi-v7a ,arm-v8a ,x86,x86_64 和mips;

classes.dex,classes2.dex,classes3.dex: 这些文件包含的就是编译后生成虚拟机认识的dex文件格式的类;

META_INF/: 包含的是签名文件(CERT.SF, CERT.RSA).清单文件MAINFEST.MF,已经一库文件的应用索引

AndroidManifest.xml: 包含核心的Android清单文件,有应用名称,版本,访问权限和应用哭等

分析“胖”的起因:

  1. 将apk包修改后缀为.zip 文件,解压后查看
  1. 使用android studio自带的Analyze APK工具(菜单Build---> Analyze APK--->选择你要分析的apk ,或者直接在android studio工程中直接双击你要分析的apk)
  1. Analyze App Size 插件(安装插件后就可以了,不过笔者在4.1.1的android studio上没有使用成功)

2)“减肥”方案

2.1 资源缩减减肥法

在你应用的build.gradle文件中,添加如下的配置:

android{
    buildTypes {
        release {
            minifyEnabled true
            shrinkResources true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }    
}  

资源缩减器shrinkResources在Gradle打包的时候可以自动忽略未使用的资源,但是他必须配合minifyEnabled才能发挥出来,代码缩减器minifyEnabled移除所有的代码后,资源缩减器才能知道哪些资源继续使用。

2.2 使用Lint静态代码分析器减肥法

菜单Analyze--->选择Run inspection by name ,然后会弹出如下图:(输入unused...)--->选择module或project ,lint 就开始帮你分析了。。。。

性能优化之APK减肥记,第2张
run_inspection_by_name

分析完成后,会展示在Inspection Results的窗口中,如下所示:

性能优化之APK减肥记,第3张
分析结果

点击左侧的一个文件后,

性能优化之APK减肥记,第4张
减肥行动图

注意:

  1. 不会扫描assets文件夹下的资源,
  1. 不会扫描通过反射应用的资源或已链接至应用的库文件
  1. 最后的删除是直接删除文件

2.3 一键移除无用资源减肥法

菜单Refactor--->Remove Unused Resource...---->选择preview 来查看有哪些资源,如下图:

性能优化之APK减肥记,第5张
一键移除无用资源preview

确保资源是确实没有使用,点击Do Refactor 直接移除,但是这个方式有个严重的问题就是针对动态获取资源id的方式会被认为没使用过,从而导致删除会引起错误,那么我们可以用下面的方法来解决:

在res/raw/文件夹中新建一个keep.xml的文件,该文件用来声明哪些资源要保留,哪些资源要舍弃。该文件是不会打包的apk中的。如下:

<?xml version="1.0" encoding="utf-8">
<resources xmlns:tools="http://schemas.android.com/tools"
    <!--声明保留的资源:多个资源用逗号隔开-->
    tools:keep="@layout/aaaaaa,@layout/bbbbbb,@drawable/ccccc"
    <!--声明放弃的资源-->
    tools:discard="@layout/ddddd"/>

以上资源缩减器只会删除代码没有引用的资源,但是他不会溢出用于不同设备配置的备用资源,我们可以使用grdle插件的资源配置属性溢出不需要的备用资源。比如我们的语言资源库,我们通过上面的分析器可以看到字符串资源包含了很多国家的语言,但是我们只需要其中的一两个语言的话,我们可以如下做:

android{
    //....
    defaultConfig{
        //......
         resConfigs "zh","en"
    }    
}
//这样就会只保存中文、英文、默认三个语言资源
性能优化之APK减肥记,第6张
资源限制配置

2.4 动态库打包配置减肥法

android{
    defaultConfig{
        ndk {
            //选择要添加的对应cpu类型的.so库。
            abiFilters 'armeabi', 'x86', 'mips', "armeabi-v7a"
            // 还可以添加 'x86', 'x86_64', 'mips', 'mips64'
        }
    }
} 

我们在集成第三方库的时候,有些提供了全平台的cpu架构,我们就需要像上面一样添加很多库,但是在android系统中,每一个CPU架构对应一个ABI ,目前支持的有armeabi-v7a ,arm64-v8a ,x86等等。目前市场上的手机设备基本上都是arm架构了,armeabi-v7a 几乎能兼容所有的arm设备,所有我们可以修改上面的配置如下:

android{
    defaultConfig{
        ndk {
            //选择要添加的对应cpu类型的.so库。
            abiFilters  "armeabi-v7a"
            // 还可以添加 'x86', 'x86_64', 'mips', 'mips64','armeabi', 'x86', 'mips',
        }
    }
}

这样就只会将armeabi-v7a的动态库打包进apk ,这样可以缩写apk的大小。

? 但是针对一些arm64的设备,我们用armeabi-v7a也可以兼容,但是性能方面就不如arm64的库,这样我们针对不同的设备可以提供不同架构的apk来安装。如下来实现:

//方案1
flavorDimensions "default"
productFlavor{
    arm32{
        dimension "default"
        ndk{
            abiFilters  "armeabi-v7a"
        }
    }
    arm64{
    dimension "default"
         ndk{
            abiFilters  "arm64-v8a"
        }
    }
}

//方案2
splits{
    abi{
        enable true
        reset()
        include "armeabi-v7a", "arm64-v8a"
        universalApk true  //是否将所有的so打包到一个apk中
    }
}

2.5 矢量图减肥法

? 在我们的app中图片资源往往占用的空间都比较大,那么对这类图片资源的减肥能快速体现效果的时候。下面我们就分情况来处理一下:

? 1)使用webp格式的图片来替换jpg ,png格式的图片

? 选择你要减肥的图片,点击右键,快捷菜单中选择convert to webp ,开始转换,如下图:


性能优化之APK减肥记,第7张
webp图片格式转换

点击“OK”,进入效果展示,如下图:


性能优化之APK减肥记,第8张
webp格式转换效果图

? 可以看到我们这样就可以将一张5.2kb的图片转换为852byte大小的webp格式的图片,同样我们还可以调整Quality,然后finish按钮,这样就将我们需要优化的图片转换好了。

? 2)使用矢量图

? 矢量图可以创建与屏幕分辨率无关的图标和其他可伸缩的媒体,在android中以VectorDrawable对象的形式来表示,不过系统在渲染每一个VectorDrawable对象的时候需要花费大量的时间,所有建议尽在小图片时使用这些矢量图。


性能优化之APK减肥记,第9张
创建矢量图

性能优化之APK减肥记,第10张
自定义矢量图

assetType: 可以选择系统的,可以加在本地的SVG ,PSD图

name可以定义为自己需要的名字。
? 点击next---> 选择存放的目录---finish, 这样一张矢量图就创建成功了。
?

 <ImageView
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:src="@drawable/vector"
        tools:ignore="MissingConstraints"/>

? 给矢量图添加颜色:

<ImageView
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:tint="#ff0000"
        android:src="@drawable/vector"
        tools:ignore="MissingConstraints" />

? 在selector中使用:

<!--定义selector:记得要放在color文件夹中作为颜色选择器-->
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="@color/colorAccent"  android:state_pressed="true"/>
    <item android:color="@color/colorPrimary"/>
</selector>

<!--在imageView中使用: 用定义的颜色selector替换tint中的固定值即可-->
<ImageView
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:tint="@color/selector"
        android:src="@drawable/vector"
        tools:ignore="MissingConstraints" />

? 3)对于一些启动页,引导页等比较大的图片,建议使用jpg格式

好了,以上就是笔者工作中用过的一些减肥方法,如后续有更好的再来完善了。。。。。。


https://www.xamrdz.com/web/2y21993886.html

相关文章: