冷啟動、熱啟動時間性能優化

用戶希望應用程序能夠快速響應并加載。 一個啟動速度慢的應用程序不符合這個期望,可能會令用戶失望。 這種糟糕的體驗可能會導致用戶在應用商店中對您的應用進行糟糕的評價,甚至完全放棄您的應用。

本文檔提供的信息可幫助您優化應用的啟動時間。 它首先解釋啟動過程的內部。 接下來,討論如何配置啟動性能。 最后,它描述了一些常見的啟動時間問題,并提供了一些關于如何解決它們的提示

Launch Internals
應用程序啟動可以發生在三種狀態之一,每種狀態都會影響您的應用程序對用戶可見的時間長度:冷啟動,熱啟動和溫熱啟動。 冷啟動,你的應用程序從頭開始。 在其他的狀態,系統需要將應用程序從后臺引向前臺。 我們建議您始終根據冷啟動的情況進行優化。 這樣做可以改善熱啟動和溫熱啟動的性能。

為了優化您的應用程序以實現快速啟動,常常需要了解系統和應用程序級別發生了什么以及它們如何交互

冷啟動

冷啟動是指應用程序從頭開始:系統的進程在開始之前還沒有創建應用程序的進程。 冷啟動發生在您的應用程序自啟動設備以來第一次啟動的情況下,或由于系統殺死應用程序。 這種類型的啟動在縮短啟動時間方面提出了最大的挑戰,因為系統和應用比其他啟動狀態有更多的工作要做。

在冷啟動開始時,系統有三項任務。 這些任務是:

  1. 加載并啟動應用。
  2. 啟動后立即顯示應用程序的空白開始窗口。
  3. 創建應用進程。

只要系統創建應用程序進程,應用程序進程就負責下一個階段。 這些階段是:

  1. 創建該應用對象
  2. 啟動主線程
  3. 創建主activity
  4. 填充views
  5. 鋪設屏幕
  6. 執行初始繪制

    一旦應用程序完成第一次繪制,系統進程就會將當前顯示的背景窗口替換為主要活動。 此時,用戶可以開始使用該應用程序。
    這里寫圖片描述

性能問題可能在創建應用程序和創建activity時出現

Application creation

當您的應用程序啟動時,空白的起始窗口將保留在屏幕上,直到系統第一次完成繪制應用程序。 此時,系統進程為應用程序換掉了啟動窗口,允許用戶開始與應用程序進行交互

如果您在自己的應用程序中重載了Application.oncreate(),系統將調用您的應用程序對象上的onCreate()方法。 之后,應用程序會生成主線程,也稱為UI線程,并執行創建主Activity的任務。

從這一點來看,系統和應用程序級別的進程按照應用程序生命周期階段進行。

Activity的創建

應用程序進程創建您的活動后,活動執行以下操作:

  1. 初始化值
  2. 調用構造方法
  3. 調用回調方法,按照activity的生命周期

通常情況下,onCreate()方法對加載時間影響最大,因為它執行的開銷最高:加載和擴充視圖,并初始化活動運行所需的對象

熱啟動
應用程序的熱啟動比冷啟動更簡單,開銷更低。 在一個溫暖的開始,所有的系統都會把你的activity帶到前臺。 如果您的所有應用程序的活動仍駐留在內存中,則應用程序可以避免重復對象初始化,布局填充和渲染

但是,如果某些內存已被清除以響應內存調整事件(如onTrimMemory()),則將響應熱啟動事件重新創建這些對象。

熱啟動顯示與冷啟動場景相同的屏幕行為:系統進程顯示空白屏幕,直到應用完成activity的渲染。

Lukewarm start

一個lukewarm start包含了在冷啟動期間發生的一些操作子集; 與此同時,它代表的不是一個熱啟動的開始。 有許多潛在的狀態可以被認為是溫和的開始。 例如:

  • 用戶退出應用程序,但重新啟動它。 該進程可能會繼續運行,但應用程序必須通過調用onCreate()從頭開始重新創建活動
  • 系統從內存中清除您的應用程序,然后用戶重新啟動它。 進程和Activity需要重新啟動,但是任務可以從saved instance state bundle 傳遞給onCreate()

分析啟動性能

為了正確地診斷開始時間性能,您可以跟蹤顯示啟動應用程序所需時間
要重現用戶體驗,請確保以非可調試模式對應用進行配置。 可調試模式啟用調試功能,導致啟動時間非典型的用戶體驗。

初始時間顯示

從Android 4.4(API級別19),logcat包含一個輸出行,其中包含一個名為Displayed的值。 該值表示啟動過程和完成在屏幕上繪制相應活動之間所經過的時間量。 經過的時間包括以下一系列事件:

  1. 啟動進程
  2. 初始對象
  3. 創建并初始化activity
  4. 填充布局
  5. 在第一時間繪制你的應用

報告的日志行與以下示例類似:

ActivityManager: Displayed   com.android.myexample/.StartupTiming: +3s534ms

如果您正在從命令行或終端跟蹤logcat輸出,則查找已用時間很簡單。 要在Android Studio中查找已用時間,您必須在logcat視圖中禁用篩選器。 禁用過濾器是必要的,因為系統服務器,而不是應用程序本身,服務于這個日志。

一旦你做了適當的設置,你可以輕松地搜索正確的術語來查看時間。 圖2顯示了如何禁用過濾器,并在底部輸出的第二行顯示了Displayed時間的logcat輸出示例。

Logcat輸出中的“顯示”度量不一定會捕獲所有資源加載和顯示之前的時間量:它會遺漏布局文件中未引用的資源或應用程序作為對象初始化的一部分創建的資源。 它排除了這些資源,因為加載它們是一個內嵌的過程,并且不會阻止應用程序的初始顯示

您也可以使用ADB Shell活動管理器命令運行您的應用程序來測量初始顯示的時間。 這是一個例子:

adb [-d|-e|-s <serialNumber>] shell am start -S -W
com.example.app/.MainActivity
-c android.intent.category.LAUNCHER
-a android.intent.action.MAIN

顯示的度量像以前一樣出現在logcat輸出中。 您的終端窗口還應顯示以下內容:

Starting: Intent
Activity: com.example.app/.MainActivity
ThisTime: 2044
TotalTime: 2044
WaitTime: 2054
Complete

-c和-a參數是可選的,并讓您為intent指定和

完全呈現的時間

您可以使用reportFullyDrawn()方法來測量應用程序啟動和完成顯示所有資源和視圖層次之間的已用時間。 在應用執行延遲加載的情況下,這可能很有價值。 在延遲加載中,應用程序不會阻止窗口的初始繪制,而是異步加載資源并更新視圖層次結構。

如果由于延遲加載,應用程序的初始顯示不包含所有資源,則可以將所有資源和視圖的加載和顯示視為一個單獨的度量標準:例如,您的UI可能已完全加載,繪制了一些文本, 但還沒有顯示應用程序必須從網絡中獲取的圖像。

為了解決這個問題,您可以手動調用reportFullyDrawn()讓系統知道您的活動已經完成了延遲加載。 使用此方法時,logcat顯示的值是從創建應用程序對象到調用reportFullyDrawn()的時間。 這里是一個logcat輸出的例子:

system_process I/ActivityManager: Fully drawn {package}/.MainActivity: +1s54ms

logcat輸出有時會包含一個總時間,正如在“初始顯示時間”中所述
如果你知道你的顯示時間比你想要的慢,你可以繼續嘗試確定啟動過程中的瓶頸

查找瓶頸的兩個好方法是Android Studio方法跟蹤工具和內聯跟蹤。 要了解Method Tracer,請參閱工具文檔。
如果您無法訪問Method Tracer工具,或無法在正確的時間啟動該工具以獲取日志信息,則可以通過在應用程序和活動的onCreate()方法中進行內嵌跟蹤來獲得類似的洞察。 要了解內聯跟蹤,請參閱跟蹤功能參考文檔以及Systrace工具

常見問題
本節討論經常影響應用程序啟動性能的幾個問題。 這些問題主要涉及初始化應用程序和活動對象,以及加載屏幕

沉重的應用初始化
當您的代碼覆蓋Application對象時,啟動性能會受到影響,并在初始化該對象時執行繁重的工作或復雜的邏輯。 如果您的應用程序子類執行不需要完成的初始化,您的應用程序可能會浪費時間在啟動過程中。 一些初始化可能是完全不必要的:例如,當應用程序實際啟動以響應意圖時,初始化主要活動的狀態信息。 意圖是,應用程序只使用以前初始化的狀態數據的一個子集。

應用程序初始化過程中的其他問題包括垃圾收集事件的影響或數量眾多,或磁盤I / O與初始化同時發生,進一步阻止初始化過程。 垃圾收集尤其是Dalvik運行時的一個考慮因素; Art運行時同時執行垃圾收集,最大限度地減少操作的影響

診斷問題
您可以使用方法跟蹤或內聯跟蹤來嘗試診斷問題。
方法追蹤
運行Method Tracer工具顯示callApplicationOnCreate()方法最終調用com.example.customApplication.onCreate方法。 如果該工具顯示這些方法需要很長時間才能完成執行,那么您應該進一步研究以查看正在進行的工作。
內聯追蹤
使用內聯追蹤來調查可能的罪魁禍首,包括:

  • 你的應用初始onCrate() 方法
  • 全局的單例對象初始
  • 任何磁盤I / O,反序列化,或瓶頸期間可能發生的緊密循環

    解決問題
    無論問題出在不必要的初始化還是磁盤I / O,解決方案都會調用延遲初始化對象:只初始化那些立即需要的對象。 例如,不是創建全局靜態對象,而是移動到單例模式,應用程序只在第一次訪問對象時創建對象。 另外,考慮使用像Dagger這樣的依賴注入框架來創建對象,并且依賴關系是當它們被首次注入時

    繁重的activity 初始化
    activity創建通常需要大量的高開銷工作。 通常,有機會優化這項工作來實現性能改進。 這些常見問題包括:

  • 填充龐大或者復雜的布局

  • 阻塞磁盤的屏幕繪圖或網絡I / O
  • 加載并解碼圖片
  • 柵格化VectorDrawable對象
  • 在activity初始化其他子系統
    解決問題重點內容
    在這種情況下,方法跟蹤和內聯跟蹤也是有用的

Method tracing
當運行Method Tracer工具時,特定的區域將關注于您的應用程序的Application子類的構造函數和com.example.custom的Application.onCreate()方法。

如果該工具顯示這些方法需要很長時間才能完成執行,那么您應該進一步研究以查看正在進行的工作。
Inline tracing
使用內聯追蹤來調查可能的罪魁禍首,包括:

  • 你的應用初始onCreate() 方法
  • 全局的單例對象初始
  • 任何磁盤I / O,反序列化,或瓶頸期間可能發生的緊密循環
    解決問題
    有很多潛在的瓶頸,但是兩個常見的問題和解決方法如下

    視圖層次越大,應用所需的時間就越多。 你可以采取兩個步驟來解決這個問題

  • 通過減少冗余或嵌套布局來平坦您的視圖層次結構
  • 不要在啟動時填充不需要顯示的部分UI。使用ViewStub對象作為應用程序可以在更合適的時間填充的子層次結構的占位符來代替。

在主線程上完成所有的資源初始化操作也會減慢啟動速度。 你可以解決這個問題如下:

  • 把所有可以通過懶加載的初始資源放到不同的線程去執行
  • 允許應用加載展示你的視圖,并且可以稍后跟新視覺屬性通過bitmaps 和其他資源。

主題啟動屏幕
您可能希望主題化您的應用的加載體驗,以便應用的啟動屏幕與應用的其余部分在主題上保持一致,而不是與系統主題一致。 這樣做可以隱藏一個緩慢的activity 啟動。

實現主題啟動屏幕的常用方法是使用windowDisablePreview主題屬性來關閉啟動應用程序時系統進程繪制的初始空白屏幕。 但是,這種方法會導致比不抑制預覽窗口的應用程序更長的啟動時間。 此外,它強制用戶在活動啟動時等待而沒有任何反饋,使他們不知道該應用程序是否運行正常。

診斷問題
您可以通過觀察用戶啟動應用程序時的慢速響應來經常診斷此問題。 在這種情況下,屏幕可能會被凍結,或者停止響應輸入
解決問題
我們建議您不要禁用預覽窗口,而要遵循常見的Material Design模式。 您可以使用該活動的windowBackground主題屬性為開始活動提供一個簡單的自定義繪圖。

例如,您可以創建一個新的可繪制文件,并從布局XML和應用程序清單文件中引用它,如下所示:
布局文件:

<layer-list xmlns:android="http://schemas.android.com/apk/res/android" android:opacity="opaque"><!-- The background color, preferably the same as your normal theme --><item android:drawable="@android:color/white"/><!-- Your product logo - 144dp color version of your app icon --><item><bitmap
      android:src="@drawable/product_logo_144dp"android:gravity="center"/></item>
</layer-list>

Manifest file:

<activity ...
android:theme="@style/AppTheme.Launcher" />

轉換回正常主題最簡單的方法是在調用super.onCreate()和setContentView()之前調用setTheme(R.style.AppTheme):

public class MyMainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {// Make sure this is before calling super.onCreatesetTheme(R.style.Theme_MyApp);super.onCreate(savedInstanceState);// ...}
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/389081.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/389081.shtml
英文地址,請注明出處:http://en.pswp.cn/news/389081.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

python:lambda、filter、map、reduce

lambda 為關鍵字。filter&#xff0c;map&#xff0c;reduce為內置函數。 lambda&#xff1a;實現python中單行最小函數。 g lambda x: x * 2 #相當于 def g(x):return x*2print(g(3))# 6 注意&#xff1a;這里直接g(3)可以執行&#xff0c;但沒有輸出的&#xff0c;前面的…

集群

原文地址&#xff1a;http://www.microsoft.com/china/MSDN/library/windev/COMponentdev/CdappCEnter.mspx?mfrtrue 本文假設讀者熟悉 Windows 2000、COM、IIS 5.0 摘要 Application Center 2000 簡化了從基于 Microsoft .NET 的應用程序到群集的部署&#xff0c;群集是一組…

Myeclipes連接Mysql數據庫配置

相信大家在網站上也找到了許多關于myeclipes如何連接mysql數據庫的解決方案&#xff0c;雖然每一步都按照他的步驟來&#xff0c;可到最后還是提示連接失敗&#xff0c;有的方案可能應個人設備而異&#xff0c;配置環境不同導致。經過個人多方探索終于找到一個簡單便捷的配置方…

cnn圖像二分類 python_人工智能Keras圖像分類器(CNN卷積神經網絡的圖片識別篇)...

上期文章我們分享了人工智能Keras圖像分類器(CNN卷積神經網絡的圖片識別的訓練模型)&#xff0c;本期我們使用預訓練模型對圖片進行識別&#xff1a;Keras CNN卷積神經網絡模型訓練導入第三方庫from keras.preprocessing.image import img_to_arrayfrom keras.models import lo…

圖卷積 節點分類_在節點分類任務上訓練圖卷積網絡

圖卷積 節點分類This article goes through the implementation of Graph Convolution Networks (GCN) using Spektral API, which is a Python library for graph deep learning based on Tensorflow 2. We are going to perform Semi-Supervised Node Classification using C…

[微信小程序] 當動畫(animation)遇上延時執行函數(setTimeout)出現的問題

小程序中當動畫animation遇上setTimeout函數內部使用this.setData函數&#xff0c;通常情況下會出現報錯。本文先告訴解決方法&#xff0c;后分析報錯原因 1.解決方法&#xff1a; 在 setTimeout() 函數的同級加上 const that this; &#xff0c;然后將this.setData換成that…

關于使用pdf.js預覽pdf的一些問題

手機應用中pdf展示使用非常廣泛&#xff0c; 一些pdf由于特殊的內容比如文字、電子簽章必須使用復雜的解析器來解析&#xff0c;當使用MultiPdf 這個庫加載&#xff0c;會使得包變得非常龐大&#xff0c; 這里我們考慮使用pdf.js 來解析pdf. 引用非常簡單&#xff0c;只需要把…

SqlHelper改造版本

using System;using System.Configuration;using System.Data;using System.Data.SqlClient;using System.Collections; /// <summary> /// SqlHelper類是專門提供給廣大用戶用于高性能、可升級和最佳練習的sql數據操作 /// </summary> public abstract c…

回歸分析預測_使用回歸分析預測心臟病。

回歸分析預測As per the Centers for Disease Control and Prevention report, heart disease is the prime killer of both men and women in the United States and around the globe. There are several data mining techniques that can be leveraged by researchers/ stat…

VMware文件共享

VMware tools 文件共享 已經安裝后&#xff1a; vmhgfs-fuse .host:/ /mnt/hgfs

npm 問題(一)

今天在使用npm安裝程序時出現了以下問題如下&#xff1a; 我解決了問題&#xff0c;這是由于緩存清除錯誤&#xff08;但他們自動修復&#xff09;有一些數據損壞&#xff0c;沒有讓JSON文件解析&#xff0c;使用以下命令可以解決&#xff1a;即&#xff1a; npm cache clean -…

UDP打洞程序包的源碼

C#實現UDP打洞 轉自&#xff1a;http://hi.baidu.com/sdfiyon/blog/item/63a6e039155e02f23a87ceb1.html 下面是UDP打洞程序包的源碼&#xff1a;//WellKnown公用庫using System;using System.IO;using System.Runtime.Serialization.Formatters.Binary;using System.Net ;usi…

NLPPython筆記——WordNet

WordNet是一種面向語義的英語詞典&#xff0c;由Princeton大學的心理學家、語言學家和計算機工程師聯合設計。它不是光把單詞以字母順序排列&#xff0c;而且按照單詞的意義組成一個“單詞的網絡”。 NLTK庫中包含了英語WordNet&#xff0c;里面共有155287個詞以及117659個同義…

crc16的c語言函數 計算ccitt_C語言為何如此重要

●●●如今&#xff0c;有很多學生不懂為何要學習編程語言&#xff0c;為何要學習C語言&#xff1f;原因是大學生不能滿足于只會用辦公軟件&#xff0c;而應當有更高的學習要求&#xff0c;對于理工科的學生尤其如此。計算機的本質是“程序的機器”&#xff0c;程序和指令的思想…

毫米波雷達與激光雷達的初探

毫米波雷達與激光雷達的初探 雷達 &#xff08;Radio Detection and Range, Radar&#xff09;是一種利用電磁波來對目標進行探測和定位的電子設備。實現距離測量、運動參數測量、搜索和發現目標、目標定位、目標特性參數分析等功能。 分類 電磁波按照從低頻到高頻的順序&…

aws spark_使用Spark構建AWS數據湖時的一些問題以及如何處理這些問題

aws spark技術提示 (TECHNICAL TIPS) 介紹 (Introduction) At first, it seemed to be quite easy to write down and run a Spark application. If you are experienced with data frame manipulation using pandas, numpy and other packages in Python, and/or the SQL lang…

沖刺第三天 11.27 TUE

任務執行情況 已解決問題 數據庫結構已經確定 對聯生成model已訓練完成 詞匹配部分完成 微信前端rush版本完成 總體情況 團隊成員今日已完成任務剩余任務困難Dacheng, Weijieazure數據庫搭建(完成&#xff09;multiple communication scripts, call APIs需要進行整合調試Yichon…

鎖是網絡數據庫中的一個非常重要的概念

鎖是網絡數據庫中的一個非常重要的概念&#xff0c;它主要用于多用戶環境下保證數據庫完整性和一致性。各種大型數據庫所采用的鎖的基本理論是一致的&#xff0c;但在具體 實現上各有差別。目前&#xff0c;大多數數據庫管理系統都或多或少具有自我調節、自我管理的功能&#x…

DPDK+Pktgen 高速發包測試

參考博客 Pktgen概述 Pktgen,(Packet Gen-erator)是一個基于DPDK的軟件框架&#xff0c;發包速率可達線速。提供運行時管理&#xff0c;端口實時測量。可以控制 UDP, TCP, ARP, ICMP, GRE, MPLS and Queue-in-Queue等包。可以通過TCP進行遠程控制。Pktgen官網 安裝使用過程 版本…

python 商城api編寫_Python實現簡單的API接口

1. get方法import jsonfrom urlparse import parse_qsfrom wsgiref.simple_server import make_server# 定義函數&#xff0c;參數是函數的兩個參數&#xff0c;都是python本身定義的&#xff0c;默認就行了。def application(environ, start_response):# 定義文件請求的類型和…