Android—屏幕適配和優化問題

各自的定義:

  • px:pixel,像素,屏幕上實際的像素點單位
  • dpi: dot per inch,每英寸多少點,該值越高,則圖片越細膩
  • dp: dip,Density-independent pixel, 設備獨立像素
  • sp: scale-independent pixel,字體大小單位。

像素密度爲160時,1dp = 1px

px = dp*(dpi/160) = dp*density

適配方法

  1. 使用wrap_content, match_parent, weight要確保佈局的靈活性並適應各種尺寸的屏幕
  2. 使用RelativeLayout或ConstraintLayout,禁用絕對佈局。
  3. 使用Nine-Patch圖片
  4. 使用Size限定符
  5. 使用Smallest-width限定符

卡頓的兩大因素:

界面繪製:主要原因是繪製的層級深、頁面複雜、刷新不合理,由於這些原因導致卡頓的場景更多出現在 UI 和啓動後的初始界面以及跳轉到頁面的繪製上。

數據處理:導致這種卡頓場景的原因是數據處理量太大,一般分爲三種情況,一是數據在處理 UI 線程,二是數據處理佔用 CPU 高,導致主線程拿不到時間片,三是內存增加導致 GC 頻繁,從而引起卡頓。

佈局優化

  1. 使用ConstraintLayout或者RelativeLayout,ConstraintLayout開銷較小,儘量減少佈局的重疊和嵌套。
  2. 父佈局的寬和高儘量設置成固定值或者match-parent,因爲這樣在測量尺寸時只需要測量一次。wrap_content,會增加measure計算成本,子View的尺寸可能會動態變化,這樣就造成了父佈局的尺寸需要多次被測量,影響性能。
  3. 刪除控件中無用屬性
  4. 通用的佈局抽出來通過include包含到指定的佈局。這樣可以實現佈局的複用,既可以提高佈局性能,也有利於以後的維護。用include時候需要注意,如果想重寫被包含佈局的layout屬性必須在include標籤內重寫layout_width和layout_height屬性,這樣重寫其它layout屬性纔有效。
  5. 如果include標籤的外層不是根佈局,用merge實現,這樣可以減少一層嵌套。用merge實現的佈局被include包含後就不能重寫其layout屬性了(因爲merge節點不是一個佈局),所以這時候你想對整個被包含佈局進行操作(比如設置間距),那麼只能在include標籤外層包一層佈局(比如RelativeLayout),通過該佈局來對被包含佈局進行整體操作
  6. ViewStub實現懶加載佈局。View.GONE方式在Inflate佈局的時候View仍然會創建對象,會實例化。通過ViewStub就可以真正實現需要時才加載佈局。

自定義View優化

  1. 減少不必要的代碼
  2. 不在 onDraw 中做內存分配的事
  3. 減少 onDraw 被調用的次數,調用視圖的setVisibility()、setEnabled()、setSelected()等都會導致視圖重繪,如果想要手動地強制讓視圖進行重繪,可以調用invalidate() 來實現。invalidate()只會重調onDraw方法,onMeasure和onLayout不會。postInvalidate方法應用在非UI線程中
  4. 減少 requestLayout 的次數,該方法會重調onDraw,onMeasure和onLayout3個方法。

節省——耗電優化

  • 計算優化
  • 避免 Wake Lock 使用不當

冷啓動與熱啓動

冷啓動
在啓動應用時,系統中沒有該應用的進程,這時系統會創建一個新的進程分配給該應用;

熱啓動
在啓動應用時,系統中已有該應用的進程(例:按back鍵、home鍵,應用雖然會退出,但是該應用的進程還是保留在後臺)

區別

  • 冷啓動:系統沒有該應用的進程,需要創建一個新的進程分配給應用,所以會先創建和初始化Application類,再創建和初始化MainActivity類(包括一系列的測量、佈局、繪製),最後顯示在界面上。
  • 熱啓動: 從已有的進程中來啓動,不會創建和初始化Application類,直接創建和初始化MainActivity類(包括一系列的測量、佈局、繪製),最後顯示在界面上。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章