1.前提
Androidスタジオ4.2.2
compileSdkバージョン 30
buildToolsVersion「30.0.3」
Android の起動ラグにより、画面上のアイコンがクリックされ、長時間待ってから応答インターフェイスが表示されたり、起動時に黒または白の画面が長時間表示されたりします。最適化する前に、フリーズがどこにあるかを分析して見つける必要があります。これは、起動が遅い理由に影響します。前回の記事では、起動フリーズに限らず、Android 開発プロセスにおけるフリーズ問題の解析方法を紹介しました。記事アドレス: Android パフォーマンス分析 --- Caton analysis_sunbinkang のブログ - CSDN ブログ
最適化の前提は、最適化できるところを分析し、ツールを使って時間がかかるところを見つけ出すことです。
2. 最適化 --- コールド スタート
今日、私たちの記事は、最適化するためのコールド スタートの問題から始まります。
Android の起動に関しては、問題をより適切かつ迅速に発見できるように、起動プロセスを大まかに知っておく必要があります。
Activity の起動には、主に 4 つのプロセスが含まれます。
SystemServer プロセス: 主にフレームワーク全体の管理を担当
アプリ プロセス: アプリ ユーザーがデスクトップ アイコンをクリックすると、Launcher プロセスが SystemServer プロセスを要求し、Zygote にインキュベーションを通知します。
Zygote プロセス: すべてのアプリケーション プロセスは Zygote によってハッチングされ、Zygote プロセスは init プロセスの子プロセスである init プロセスによってハッチングされます。
ランチャー プロセス: Zygote プロセスによって孵化した最初のアプリケーション プロセス。
Activity の起動には主に 7 つの段階があります
第 1 段階: Launcher は AMS に新しいアクティビティを開始するように通知します (Launcher が配置されているプロセスで実行されます)。
第 2 段階: AMS は最初にアクティビティの正確性をチェックし、正しい場合はアクティビティの情報を一時的に保存します。次に、AMS は Launcher プログラムにアクティビティを一時停止するように通知します (AMS が配置されているプロセスで実行されます)。
第 3 段階: ランチャーのアクティビティを一時停止し、一時停止したことを AMS に通知します (ランチャーが配置されているプロセスで実行されます)。
第 4 段階: アクティビティが配置されているプロセスが存在するかどうかを確認します. 存在する場合は、プロセスに直接通知し、プロセス内のアクティビティを開始します. 存在しない場合は、Process.start を呼び出して新しいプロセスを作成します. (ソケットと Zygote 通信を介して内部的に AMS プロセスで実行され、新しいプロセスをフォークします)
第 5 段階: ActivityThread インスタンスを作成し、いくつかの初期化操作を実行してから、ループ サイクルに入ります。(新しく作成したアプリのプロセスで実行)
第 6 段階: 新しいアプリケーション プロセスによって送信された通信要求を処理して作成プロセスを完了し、アプリケーションをバインドするように新しいアプリケーションに通知します。Application が存在しない場合、LoadedApk.makeApplication が呼び出されて新しい Application オブジェクトが作成されます。そして、対象のActivityコンポーネントを起動するプロセスに通知します(AMSプロセスで実行されます)。
第 7 段階: MainActivity クラスをロードし、onCreate ステートメント サイクル メソッドを呼び出します (新しく開始されたアプリ プロセスで実行されます)。
上記の起動プロセス分析から、最適化を開始できるポイントは、主にアプリケーションの oncreate ライフサイクルと、アクティビティの onCreate または onResume、onStart およびその他のライフサイクル であることがわかります。他のプロセスはすべて Android システム コールであり、通常は介入できません。
最適化 1. 白黒画面の問題を解決するためのテーマ切り替え
システムがアプリを読み込んで起動すると、それに応じた時間がかかり、ユーザーがアプリのアイコンをクリックしたときに「遅延」を感じます. この問題を解決するために、Google のアプローチはアプリを作成することです.空白のページを表示し、Google はデフォルト テーマのデフォルトの背景ウィンドウを白または黒に設定します。これにより、ユーザーはアイコンをクリックした直後に応答を体験できます。アプリケーションまたはアクティビティの起動プロセスが遅すぎて、システムの BackgroundWindow が時間内に置き換えられない場合、起動時に白または黒の画面が表示されます (テーマ テーマがダークかライトかによって異なります)。起動時の白黒画面の問題を解消するために、ほとんどのアプリはテーマに独自の背景画像を設定することで解決しています。
res の values フォルダーの下にある styles.xml または themes.xml にスタートアップ テーマを追加します。
<style name="Launcher">
<item name="android:windowBackground">@drawable/bg</item>
</style>
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@color/white" />
<item>
<bitmap
android:gravity="center"
android:scaleType="centerCrop"
android:src="@drawable/icon_qq_login" />
</item>
</layer-list>
概要: この最適化ソリューションは実際には一時的な解決策であり、恒久的なソリューションではありません. ユーザーを欺くという観点からすると、高速起動の錯覚を生み出します. しかし、白い画面や黒い画面を見るよりはましです。
最適化 2. idleHandler を使用して処理を遅らせる
実際のプロジェクトでは、Youmeng と Tencent TBS は時間がかかることがわかりました.ビジネスを考慮しながら、CPU がアイドル状態になった後に初期化できるため、これらのサードパーティの初期化をここに入れます.
Looper.myQueue().addIdleHandler {
// TODO:依赖库的初始化
false
}
IdleHandler はコールバック インターフェイスであり、実装クラスは MessageQueue の addIdleHandler を介して追加できます。MessageQueue 内のタスクが一時的に処理される場合 (新しいタスクがない場合、または次のタスクが遅延している場合)、この時点でこのインターフェイスがコールバックされ、false が返された場合は削除され、true が返された場合は、メッセージが次に処理されるときになります。
最適化 3. レイアウトの最適化
レイアウトのネスト レベルを減らし、include、viewStub、meger などのタグを使用する
最適化 4. 非同期ロード
非同期スレッドを使用していくつかのロジックをロードします。使用できるもの: RxJava、スレッド プール、AsyncTask、IntentService、HandlerThread、Thread
最適化 5. 遅延読み込み
たとえば、ホームページが viewpager+fragment の場合、遅延読み込みの最適化を使用できます
最適化 6、StrictMode 厳格モード
StrictMode は、意図せずに行っている可能性のある時間のかかる不合理なことを検出し、それらを修正できるように注意を喚起する開発者ツールです。StrictMode は、アプリケーションのメイン スレッドでファイル ディスクまたはネットワーク アクセスをキャプチャするために最もよく使用されます。ディスクとネットワークの操作をメイン スレッドから切り離すことで、よりスムーズで応答性の高いアプリケーションを実現できます。
アプリケーションの OnCreate メソッドで厳密モードを設定します。
fun setStrictMode() {
if (BuildConfig.DEBUG) {
//线程检测策略
StrictMode.setThreadPolicy(
StrictMode.ThreadPolicy.Builder()
.detectDiskReads() //读、写操作
.detectDiskWrites()
.detectNetwork() // or .detectAll() for all detectable problems
.penaltyLog()
.build()
);
StrictMode.setVmPolicy(
StrictMode.VmPolicy.Builder()
.detectLeakedSqlLiteObjects() //Sqlite对象泄露
.detectLeakedClosableObjects() //未关闭的Closable对象泄露
.penaltyLog() //违规打印日志
.penaltyDeath() //违规崩溃
.build()
);
}
}
これは、後でリリースされるときにこれらの問題を見つけるのではなく、問題をより適切かつタイムリーに見つけるのに役立ちます。
3. まとめ
パフォーマンス分析は、プロジェクトの実際の状況に応じて分析および最適化する必要があります。パフォーマンスの最適化は時間のかかるプロセスであるため、オンラインでリリースしようとしているときにパフォーマンスの分析と最適化を行うのではなく、通常の開発プロセスでこれらの問題を回避するために最善を尽くす必要があります。また、より多くの時間と労力を要します。したがって、良い発達習慣を身につけることは、私たちがより良く成長するのに役立ちます.