簡単な紹介
プロジェクトの継続的な反復では、リソースファイルを使用してコードの量が増え続けています。ある日突然あなたはAPKのサイズを最適化するために、あなたの上司やリーダーを呼び出す場合APKファイルは、その後、より多くのパッケージがあるでしょう、あなたは我々が分析し、この記事を最適化するために一緒に行くだろう、それは正当化されない最適化する方法がわかりませんそれのAPKのボリュームサイズ。
最初の最適化の図を見た後に及ぼす影響
APKの資源消費解析
注意:
必要であれば、私はオープンソースプロジェクトのGitHubの比較的高い人気を探していた、あなたがクリックすることができますダウンロードして自分で何かを試してみてください。
ビルド解析ツールを直接使用するAS / APKを分析
リソースファイルは、ほとんどを占有している上記図11bから> classes.dex> RES>資産を描画します。
ここでは、それAPKのサイズを小さくする方法を見てみましょう
APK 8つの大きなボリュームの最適化
1.画像フォーマットを変換WEBP
WEBPコンセプト
WEBPはVP8ビデオ符号化フォーマットから導出されたイメージファイル形式の可逆圧縮を提供しながら、非可逆圧縮です。WEBPは、もともと2010年にリリースされ、ネットワーク上の画像ファイルの転送時間を短縮することを期待して、ファイルサイズを小さくするために、同じ品質のJEPG形式の画像を達成することを目指しています。2011年11月8日には、GoogleがWEBPサポート可逆圧縮と透明色機能を作り始めました。
Googleの以前のテスト、WEBP可逆圧縮、ネットワーク上で検出されたPNGファイルのファイルサイズ未満の45パーセントによると、彼らはPNGCRUSHと処理PNGOUTでPNGファイルを使用している場合でも、WEBPはまだ28%で、ファイルサイズを小さくすることができます。今のところ、WEBPは、画像のサイズが平均70%の減少を行うことができます。WEBP画像フォーマットは、今後の動向です。
PNG / WEBPにJPG
フォーマットをWEBPする画像やフォルダ、右セレクト変換をクリックして、PNG / JPG画像圧縮形式はWEBP絵です。
最後に、我々はたったの約200未満KB減少し、原因の小さな画像に、すでにあまりにも多く、あまりありませんが、画像リソースを投影することが可能です。
シナリオと利点
- 客户端软件,内嵌了基于 Chromium 的 webview,这类浏览器中应用的网页是可以完全使用WebP 格式,提升加载渲染速度,不考虑兼容。
- 用 node-webkit 开发的程序,用 WebP 可以减少文件包的体积。
- 移动应用 或 网页game ,界面需要大量图片,可以嵌入 WebP 的解码包,能够节省用户流量,提升访问速度优势:
- 对于 PNG 图片,WebP 比 PNG 小了45%。
2. 去除多语言
在 app/build.gradle 添加
android{
...
defaultConfig{
...
//只保留英语
resConfigs "en"
}
}
这里我们发现减少了大概 200 kb
3. 去除不必要 so 库
通过反编译 Android 微信版本 得知,微信也只适配了 armeabi-v7a 架构,那么我们删掉其它库的支持吧。
android{
...
defaultConfig{
...
ndk {
//设置支持的SO库架构
abiFilters "armeabi-v7a"
}
}
}
又优化了差不多 600 kb ,继续。
4. 去除无用资源 Link 检查(谨慎删除)
概念
Lint 是 Android Studio 提供的 代码扫描分析工具,它可以帮助我们发现代码结构 / 质量问题,同时提供一些解决方案,而且这个过程不需要我们手写测试用例。代码迭代版本一多,很容易会遗留一些无用的代码、资源文件,我们可以使用 Lint 进行清除。
怎么使用 Link 检查
打开 AS 工具,找到 Analyze > Run Inspection By Name > unused resources
优化
发现我们 link 大概优化了 700 kb继续。
注意
因为 link 是检查有没有引用来做的判断是否使用了资源,那么如果是这种方式勒,所以在删除的时候一定要谨慎。
//动态获取资源 id , 未直接使用 R.xx.xx ,则这个 id 代表的资源会被认为没有使用过(类似不能混淆反射类)
int indetifier =getResources().getIdentifier("img_bubble_receive", "drawable", getPackageName()); getResources().getDrawable(indetifier);
5. 开启混淆
优化了大概 1.7M 继续。
6.移除无用资源 shinkResource
-
开启 shinkResource = true
buildTypes { release { minifyEnabled true shrinkResources = true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } debug { shrinkResources = true minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } }
这个有可能 link 删除了无用资源,所以没有在优化了
7.开启删除无用资源 (严格模式和普通模式) - 这个我这里就不可测试,你们下来可以测试下效果
普通模式也就是自定义模式
如果您有想要保留或舍弃的特定资源,请在您的项目中创建一个包含 <resources>
标记的 XML 文件,并在 tools:keep
属性中指定每个要保留的资源,在 tools:discard
属性中指定每个要舍弃的资源。这两个属性都接受逗号分隔的资源名称列表。您可以使用星号字符作为通配符。
例如:
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"
tools:keep="@layout/l_used*_c,@layout/l_used_a,@layout/l_used_b*"
tools:discard="@layout/unused2" />
将该文件保存在项目资源中,例如,保存在 res/raw/keep.xml
。构建不会将该文件打包到 APK 之中。
指定要舍弃的资源可能看似愚蠢,因为您本可将它们删除,但在使用构建变体时,这样做可能很有用。例如,如果您明知给定资源表面上会在代码中使用(并因此不会被压缩器移除),但实际不会用于给定构建变体,就可以将所有资源放入公用项目目录,然后为每个构建变体创建一个不同的 keep.xml
文件。构建工具也可能无法根据需要正确识别资源,这是因为编译器会添加内联资源 ID,而资源分析器可能不知道真正引用的资源和恰巧具有相同值的代码中的整数值之间的差别。
严格模式
正常情况下,资源压缩器可准确判定系统是否使用了资源。不过,如果您的代码调用 Resources.getIdentifier()
(或您的任何库进行了这一调用 - AppCompat 库会执行该调用),这就表示您的代码将根据动态生成的字符串查询资源名称。当您执行这一调用时,默认情况下资源压缩器会采取防御性行为,将所有具有匹配名称格式的资源标记为可能已使用,无法移除。
例如,以下代码会使所有带 img_
前缀的资源标记为已使用。
String name = String.format("img_%1d", angle + 1);
res = getResources().getIdentifier(name, "drawable", getPackageName());
资源压缩器还会浏览代码以及各种 res/raw/
资源中的所有字符串常量,寻找格式类似于 file:///android_res/drawable//ic_plus_anim_016.png
的资源网址。如果它找到与其类似的字符串,或找到其他看似可用来构建与其类似的网址的字符串,则不会将它们移除。
これらは、デフォルトの圧縮モードで有効なセキュリティの例です。しかし、あなたが決定するのに使用されているリソースのみを保持この「調製する」アプローチ、および指定されたリソースのコンプレッサーを無効にすることができます。で、これを実行するにはkeep.xml
、ファイルshrinkMode
のように設定strict
、次のとおりです。
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"
tools:shrinkMode="strict" />
あなたが実際にしている場合は厳しい圧縮モードが有効になっている、そして使用する必要があり、動的に生成された文字列を含んでなる(上図のように)また、コードリソースを参照しtools:keep
、手動でこれらのリソースを保持している属性を。
8. AndResGuardマイクロチャネルリソース圧縮方式
AndResGuardは何ですか
AndResGuardは、その原則は、Java ProGuardのに似て、APKのサイズを小さくするためのツールですが、リソースのみのため。これは、そうでない場合は、冗長リソースパスは/ R / Dとなる微信例えばRES /描画可能/のために、短縮されるであろう。
なぜAndResGuard
過去の開発では、我々は通常のみ読みやすさの解像度が強すぎるすべてのファイル名をフォルダ、リソースファイルは、他人の前で露出して、コードを混乱させる。
使用後の効果
AndResGuard設定
-
Build.gradleプロジェクトのルートディレクトリには、依存プラグインを追加します。
dependencies { classpath 'com.tencent.mm:AndResGuard-gradle-plugin:1.2.16' }
- appディレクトリには、作成and_res_guard.gradleファイルを
apply plugin: 'AndResGuard'
andResGuard {
mappingFile = null
use7zip = true
useSign = true
keepRoot = false
compressFilePattern = [
"*.png",
"*.jpg",
"*.jpeg",
"*.gif",
"resources.arsc"
]
whiteList = [
// your icon
"R.drawable.icon",
// for fabric
"R.string.com.crashlytics.*",
// for umeng update
"R.string.tb_*",
"R.layout.tb_*",
"R.drawable.tb_*",
"R.drawable.u1*",
"R.drawable.u2*",
"R.color.tb_*",
// umeng share for sina
"R.drawable.sina*",
// for google-services.json
"R.string.google_app_id",
"R.string.gcm_defaultSenderId",
"R.string.default_web_client_id",
"R.string.ga_trackingId",
"R.string.firebase_database_url",
"R.string.google_api_key",
"R.string.google_crash_reporting_api_key",
//友盟
"R.string.umeng*",
"R.string.UM*",
"R.layout.umeng*",
"R.drawable.umeng*",
"R.id.umeng*",
"R.anim.umeng*",
"R.color.umeng*",
"R.style.*UM*",
"R.style.umeng*",
//融云
"R.drawable.u*",
"R.drawable.rc_*",
"R.string.rc_*",
"R.layout.rc_*",
"R.color.rc_*",
"R.id.rc_*",
"R.style.rc_*",
"R.dimen.rc_*",
"R.array.rc_*"
]
sevenzip {
artifact = 'com.tencent.mm:SevenZip:1.2.10'
}
}
-
追加アプリモジュール内のbuild.gradleファイル
apply from: 'and_res_guard.gradle'
- 終了梱包レンダリングした後、
約1M圧縮リソース
概要
- 大きなボリュームのプロジェクト、より多くのリソースを、より顕著な結果。
- リンクはリソースを使用して削除、我々は先に、バックアップの、慎重でなければなりません。
- ここでちょうど10 Mプロジェクト自体の上にあるので、最終的には4.5 Mダウンを最適化します。それはまだ容易ではありません。
さて、あなたは記事がかなり便利に感じる場合は、ここで終了する記事は、あなたの友人にそれらをお勧めしたいことがあります。
〜自由な外観を受信する887 084 983:最後に、ここに興味を持ってパートナーがグループに追加することができ、大規模なビデオコレクションを整理、Androidは自分自身、面接書類についての学習です