パフォーマンスの最適化シリーズ
簡単な紹介
プロジェクトの継続的な反復では、リソースファイルを使用してコードの量が増え続けています。ある日突然あなたは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減少し、原因の小さな画像に、すでにあまりにも多く、あまりありませんが、画像リソースを投影することが可能です。
シナリオと利点
- クロムのWebViewに埋め込まれたクライアントソフトウェアは、完全にWEBPフォーマットを使用することができるウェブ・ブラウザ・アプリケーションのこのタイプは、関係なく、互換性の、高速負荷をレンダリング強化します。
- ノードWebKitのプログラム開発、ボリュームはWEBPファイルパッケージを使用して低減することができます。
- モバイルアプリケーションやウェブゲームは、インターフェイスは、あなたが、ユーザーがトラフィックを保存することができ、WEBPコーデックパックを埋め込むアクセス速度の優位性を向上させることができ、写真をたくさん必要です。
- PNGの画像では、PNGよりも45%小さいWEBP。
2.多言語を削除します
アプリ/ build.gradleに追加
android{
...
defaultConfig{
...
//只保留英语
resConfigs "en"
}
}
复制代码
ここでは、減少について200キロバイトを見つけます
3.不要なのでライブラリを削除します
アンドロイドをコンパイルマイクロチャネルバージョン、マイクロチャネルのみarmeabi-v7aアーキテクチャに合わせて、我々は他のライブラリは、それを削除サポートしています。
android{
...
defaultConfig{
...
ndk {
//设置支持的SO库架构
abiFilters "armeabi-v7a"
}
}
}
复制代码
そして引き続き、ほぼ600キロバイトを最適化します。
4.不必要なリソースにリンクチェックを外します(注意は削除)
コンセプト
リントは、Androidのメーカーが提供するコード分析ツールをスキャンしている、それはいくつかのソリューションを提供しながら、コードの構造/品質の問題を発見私たちを助けることができ、このプロセスは、私たちに手書きのテストを必要としません。1以上のコードの反復バージョンは、我々がリントをクリア使用することができ、未使用のコード、リソースファイルを残すことは容易です。
リンクを確認する方法
ASオープンツール、> Runの検査によって名を分析>未利用資源を見つけます
最適化
我々が見つかりました。およそ700キロバイトの継続リンクを最適化。
注意を払います
リンクが資源の利用かどうかを判断するために行うには言及されていないので、これはルへの道である場合、削除する場合、その慎重でなければならないチェックすることですので。
//动态获取资源 id , 未直接使用 R.xx.xx ,则这个 id 代表的资源会被认为没有使用过(类似不能混淆反射类)
int indetifier =getResources().getIdentifier("img_bubble_receive", "drawable", getPackageName()); getResources().getDrawable(indetifier);
复制代码
5.ターン混乱
混乱は、私は再び上の記事を見てお勧めできるか分からないがある場合は、パフォーマンスの最適化(XI)ProGuardのは、コードとリソースを圧縮します
1.7Mはおそらく最適化を続行します。
6.未使用のリソースを削除するshinkResource
-
オープンshinkResource =真
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' } } 复制代码
無用のリソースを削除することができ、リンク、そうで何の最適化はありません
7.電源を入れ、不要なリソース(strictモードと通常モード)を削除 - 私はここでテストすることができないことを、あなたはダウンの下での効果をテストすることができます
ノーマルモードではカスタムモードであります
あなたが特定のリソースを保持するか破棄したい場合は、あなたのプロジェクトが含まれている作成し<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を追加するので、むしろ同じ値を持つように起こるアナライザは、基準積分値を実際のリソースとコードの違いを知らないかもしれないリソース、必要なリソースを特定しない場合があります。
strictモード
通常の状況下では、リソース圧縮機システムは、正確リソースの使用かどうかを判定することができます。しかし、あなたのコードの呼び出しの場合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
リソースURLを。それはこれに類似の文字列を見つけ、またはその他の文字列を見つけた場合はそれらを削除しないであろうその一見似たURLを構築するために使用することができます。
これらは、デフォルトの圧縮モードで有効なセキュリティの例です。しかし、あなたが決定するのに使用されているリソースのみを保持この「調製する」アプローチ、および指定されたリソースのコンプレッサーを無効にすることができます。で、これを実行するには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ダウンを最適化します。それはまだ容易ではありません。
ます。https://juejin.im/post/5d0627f7f265da1bd4247e76で再現