从Play服务巨人过滤资源,使您的APK变小

关于Google Play服务的庞大性质以及为什么应该将其分割成更多的库,已经有很多文章了。 现在,让APK保持小的解决方法是使用proguard去除未使用的引用。 这对于classes.dex非常有效,但对于包含的资源不是。

我得到了1 MB附加的未使用的资源,并与捆绑的Android Wear应用程序这个开销加倍。 所以我的APK比需要的大2 MB。

我想知道在Gradle中是否有一些简单的方法可以从APK生成的依赖项AARs中排除一些资源。

看来Gradle Android插件中的AAPT选项只允许过滤资源 。

我正在考虑挂钩一些自定义aapt脚本,在使用aapt签名APK之前,会调用remove aapt资源列表。

别人有更简单的解决scheme吗?

Solutions Collecting From Web of "从Play服务巨人过滤资源,使您的APK变小"

经过一番研究,我发现了下面的次优解决scheme。 我不得不手动列出所有不需要的资源(幸运的是,模式是适用的),并确保也删除它们被引用的所有文件。 下面是一个例子,使我的磨损应用程序APK从1.5 MB到300kb,APK正常工作没有问题。

我必须创build我自己的任务stripResources并将其挂钩在标准Android插件任务mergeReleaseResourcesprocessReleaseResources

 task stripResources << { println "Custom resource stripping in: $buildDir" delete fileTree(dir: "$buildDir", include: "**/layout/confirmation_activity_layout.xml") delete fileTree(dir: "$buildDir", include: "**/layout/watch_card_content.xml") delete fileTree(dir: "$buildDir", include: "**/common_signin*.png") delete fileTree(dir: "$buildDir", include: "**/drawable/common_signin*.xml") delete fileTree(dir: "$buildDir", include: "**/generic_confirmation*.png") delete fileTree(dir: "$buildDir", include: "**/drawable/confirmation_*.xml") delete fileTree(dir: "$buildDir", include: "**/drawable/card_background.xml") delete fileTree(dir: "$buildDir", include: "**/card_frame*.png") delete fileTree(dir: "$buildDir", include: "**/go_to*.png") delete fileTree(dir: "$buildDir", include: "**/drawable/go_to_*.xml") delete fileTree(dir: "$buildDir", include: "**/ic_plusone*.png") delete fileTree(dir: "$buildDir", include: "**/powered_by_google*.png") // if you only have English you can teh following to filter out some GPS texts wich also take few hundreds of kb // delete fileTree(dir: "$buildDir", include: "**/values-*/values.xml") } tasks.whenTaskAdded { task -> if (task.name == 'processReleaseManifest') { task.dependsOn stripResources } } 

您可以为常规Android APK做类似的任务。

从Android Gradle插件的0.14版本开始,可以像这篇文章中提到的那样自动完成:

 android { buildTypes { release { minifyEnabled true shrinkResources true } } } 

shrinkResources是一个标志,告诉编译器跳过任何未被引用的资源。 minifyEnabledminifyEnabled的新名称,必须启用shrinkResources才能工作。

感谢Petr Nalevka富有洞察力的回答,我提出了以下解决scheme(又名丑陋的黑客)。

此代码删除hdpi,xhdpi,xxhdpi等下的所有PNG可绘制表,只保留mdpi(最小文件大小)的绘图。 只有在mdpi下有一个兄弟,也就是说如果他们可以安全的移除,Drawable才会被移除。 Google Play服务应该保持完整的function。

一个任务被注册为每个应用程序变体,所以这个代码适用于多种产品风格。

 applicationVariants.all { variant -> def variantCamelName = variant.name.substring(0, 1).toUpperCase() + variant.name.substring(1) def stripResourcesTask = task("strip${variantCamelName}Resources") { doFirst { def resDir = "$buildDir/intermediates/res/merged/$variant.dirName" def gpsDir = "$buildDir/intermediates/exploded-aar/com.google.android.gms" fileTree(dir: "$gpsDir", include: "**/drawable-*/*.png").each { resFile -> if (!resFile.parentFile.name.endsWith("-mdpi")) { def resName = resFile.name def resDirName = resFile.parentFile.name def mdpiFile = "$resFile.parentFile.parentFile/drawable-mdpi/$resName" if (file(mdpiFile).file) { def files = fileTree(dir: "$resDir", include: "**/${resDirName}/${resName}") // files.each { f -> println "Deleting $f..." } delete files } } } } } tasks["merge${variantCamelName}Resources"].finalizedBy stripResourcesTask } 

testingAndroid Studio 1.3.0,Gradle插件1.3.0版,构build工具版本22.0.1和GPS版本7.5.0。

我是一个Groovy noob,所以这可能不是最优雅的解决scheme。