第2部分:缩小代码

在本章中,您将找到适用于几乎所有应用程序的建议。这一切都是为了保持代码库的清洁,检查依赖关系,并为您提供帮助完成这些任务的工具。

Dex代码缩小

您要做的第一件事是启用内置缩小器。它将尝试剥离任何未使用的类和类成员,以及使用较短的名称重命名任何标识符。这两个操作都会使得到的代码变小,但后者会使调试变得很麻烦,所以我建议你只为你的发布构建类型启用缩小:

的build.gradle

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

第二行为ProGuard规则格式的minifier提供配置文件。第一个配置文件(Sdk / tools / proguard / proguard-android.txt)包含在SDK中,并包含每个Android项目的一些理智默认值。查看这些规则可以帮助您熟悉Proguard配置语法。例如,这可以保留(换句话说,防止被删除或重命名)View子类中的任何setter或getter方法:

#在视图中保留setter,这样动画仍然可以工作。
 -keepclassmembers public class * extends android.view.View { 
    void set *(***); 
    ***得*(); 
}

运气好的话,您的应用程序将使用默认配置。在构建过程中,名为AAPT的工具还会生成必要的规则,以保留Manifest中提到的所有活动和其他组件,以及XML布局中使用的任何视图。库依赖项应通过消费者ProGuard文件提供其minifier配置,但有时它们仅在其网站或手册上提供必要的ProGuard规则。在这种情况下,您需要将它们复制到app / proguard-rules.pro文件中。

遗憾的是,在启用缩小功能后,您的应用程序将无法在运行时编译或中断,通常是通过为minifier删除的类抛出ClassNotFoundException。要解决此问题,您需要在app /文件夹中创建一个proguard-rules.pro文件,并提供摆脱编译时警告所需的规则(查看消息日志以获取信息)。您还必须确保保留在运行时使用的任何类和成员,但是被minifier剥离。这些通常是代码的一部分,可以通过反射访问。

一个特定情况是XML布局中的自定义属性将类名称作为String,例如设置RecyclerViewlayoutManager


在这种情况下,AAPT将无法确定类的使用情况并生成必要的ProGuard规则。要应用修复,您应该在ProGuard配置中添加以下行,以防止GridLayoutManager类及其任何公共和受保护方法被删除或重命名:

-keep public class android.support.v7.widget.GridLayoutManager { 
    public protected *; 
}

要检查您编写的配置规则是否具有所需的效果,可以使用ClassyShark等工具检查生成的APK中的classes.dex文件。彻底测试您的应用程序也很重要!应用程序打开而不崩溃的事实并不表示正确的minifier配置。您必须测试应用中的每个屏幕和用户流是否崩溃。(我可以建议查看Android测试支持库和Espresso吗?:)

将ProGuard映射上载到Play

分析在用户设备上运行的混淆代码引发的异常,直到最近才有点不方便。通常,您必须从Play Developer Console复制堆栈跟踪,并使用计算机上的工具以及在编译时生成的ProGuard映射文件来解码原始类和方法名称。


第2部分:缩小代码_第1张图片
image.png

Play Developer Console现在可以选择将映射文件与APK一起上传,并在Crashes和ANRs面板中显示反混淆堆栈跟踪。请记住,您使用的映射文件必须来自与发行版APK完全相同的编译运行。

注意:您将在此路径下的项目文件夹中找到mappings.txt文件: /build/outputs/mapping/mapping.txt

图书馆的ProGuard配置

如果要构建要在其他需要ProGuard规则的项目中使用的AAR库,则应使用consumerProguardFiles选项将ProGuard配置文件与AAR打包在一起。这样,使用您的库的任何人都不必担心在启用缩放器时手动添加规则。在手册中使用库编译项目时,还要确保提供有关任何其他要求的信息。

的build.gradle

android { 
    ... 
    defaultConfig { 
        consumerProguardFiles“proguard-rules.txt” 
    } 
}

对Google Play服务使用粒度依赖关系

第2部分:缩小代码_第2张图片
image.png

在项目中使用Google Play Services库时,请记住切换到粒度依赖项。这意味着如果您只是使用广告,地图或GCM等几项功能,那么您将无法进入整个客户端库。您可以在developers.google.com上使用包含所有Gradle依赖关系字符串的表格。顺便说一句,ProGuard消费者规则包含在Play服务中,因此如果您为构建启用代码缩减器,它们应该可以正常工作。

追踪依赖关系

开发Android的好处是,如果你有问题,可能有人已经解决了它。随着项目的增长,您通常会引入越来越多的外部依赖项来加速开发时间。最常见的可能是用于向后兼容的Android支持库,Play服务,图像加载库,HTTP客户端和各种其他SDK ......

开发人员经常问我:我应该使用哪个图像库?我的项目有多少依赖项太多了?这些问题没有确切的答案。如果你真的需要使用一个库,因为它解决了你的问题(并且你理解了它的缺点),那就去吧。拥有合适的工具来帮助您确定它对项目规模的影响是非常重要的,这样您就可以做出明智的决定。

传递库依赖项

当你认为你只是“只是”添加一个小帮助库时,突然你的Dex大小爆炸并且你的方法计数遍及屋顶,这可能是因为你通常在build.gradle文件中看不到的传递依赖。幸运的是,有一些工具可以帮助:

$ ./gradlew app:依赖项
...
compile  - 用于编译主要源的类路径。
+  -   -  com.android.support:appcompat-v7:23.1.1 
| \  -   -  com.android.support:support-v4:23.1.1 
| \  -   -  com.android.support:support-annotations:23.1.1 
+  -   -  com.android.support:cardview-v7:23.1.1 
+  -  com.android.support:design:23.1.1 
| +  -   -  com.android.support:appcompat-v7:23.1.1(*)
| +  -   -  com.android.support:recyclerview-v7:23.1.1 
| | +  -   -  com.android.support:support-annotations:23.1.1 
| | \  -   -  com.android.support:support-v4:23.1.1(*)
| \  -   -  com.android.support:support-v4:23.1.1(*)+ 
-  com.android.support:recyclerview-v7:23.1.1(*) 
\  -  com.android.support.test.espresso :咖啡怠速资源:2.2.1

<模块名>:依赖命令给你的每个库在您的项目和它的依赖关系树的概述。版本号旁边的星号(*)告诉您之前在输出中已经提到了这个特定的依赖关系,因此无论如何它都会包含在您的项目中,除非您删除它的所有其他实例。

注意:如果您使用的是产品风格,并且您只需要一个库用于应用程序的某些变体(例如,仅适用于免费版本的广告SDK),您可以指定以您的风味名称为前缀的
依赖项,例如 依赖项{freeCompile'...' }。

使用ClassyShark检查Dex文件

有时,为了保护开发人员免受版本冲突的影响,库会直接在其代码中包含其依赖项,但包含更改的包名称,基本上会隐藏原始版本。这也意味着您不会在Gradle依赖关系树中看到这种依赖关系。

如果您希望更好地查看APK中打包的确切类和包名称,可以使用ClassyShark检查您的Dex文件。它也非常适合测试您的ProGuard规则,以确切了解它们对最终APK的影响。

第2部分:缩小代码_第3张图片
image.png

注意:作为奖励,ClassyShark将显示包裹的方法计数,这可能有助于您识别最大的多指数违规者。

image

image

+qq群457848807:。获取以上高清技术思维图,以及相关技术的免费视频学习资料

你可能感兴趣的:(第2部分:缩小代码)