1. 程式人生 > >App效能優化之View優化(2)——UI問題的解決

App效能優化之View優化(2)——UI問題的解決

一.概況

上一篇中App效能優化之View優化(1)——UI問題的檢測主要講的是我們在寫完程式碼之後,如何發現程式碼中的問題。從問題中提取經驗,規範好自己之後的程式碼編寫,本文就是講如何規範的進行UI關聯程式碼的書寫。

二.主要的點

  • View控制元件的選擇和佈局檔案層級優化;
  • Include,Merge,ViewStub等標籤的使用;
  • 自定義View中關鍵步驟中減少耗時操作;
  • 非圖片型別Drawable的使用;

三.View控制元件的選擇和層級優化

3.1原則:

儘量較少層級;使用高效的VIew控制元件;

3.2選擇View控制元件:

常用的控制元件有LinearLayout和RelativeLayout和ConstraintLayout和FrameLayout在他們中做出選擇。
1.層級儘量減少:能用ConstraintLayout或者RelativeLayout來減少層級,不用LinearLayout;(ConstraintLayout較RelativeLayout有更高的效率推薦使用)
2.多層級時候,相同層級的用LinearLayout不用RelativeLayout;(前者在measure,layout的過程中有更好的效率,這裡不展開說明,我們可以使用上一篇文章中Hierarchy View工具進行驗證

,檢視measure,layout,draw的時間,有興趣可以驗證一下,這裡不贅述)
3.作為容器控制元件的時候用FrameLayout;(單個的,如裝Fragment的容器)

3.3去掉其他不必要的背景

3.3.1去掉window的預設背景

當我們使用了Android自帶的一些主題時,window會被預設新增一個純色的背景,這個背景是被DecorView持有的。當我們的自定義佈局時又添加了一張背景圖或者設定背景色,那麼DecorView的background此時對我們來說是無用的,但是它會產生一次Overdraw,帶來繪製效能損耗。
我們在Application層級或者Activity層級,在theme中更改windowbackground屬性為null。

android:windowbackground="null"

3.3.2去掉其他不必要的背景

有時候為了方便會先給Layout設定一個整體的背景,再給子View設定背景,這裡也會造成重疊,如果子View寬度mach_parent,可以看到完全覆蓋了Layout的一部分,這裡就可以通過分別設定背景來減少重繪。或者子View沒有要求背景,那麼給父VIew添加了背景就可以了。

四.Include,Merge,ViewStub等;

4.1Include標籤來進行佈局複用

多個頁面擁有相同的區域性佈局的時候,並且這部分佈局改動的可能性較小或者不動,那麼就用Include標籤。

4.2用Merge標籤去除多餘層級

Merge意味著合併,在合適的場景使用Merge標籤可以減少多餘的層級。Merge標籤一般和Include標籤搭配使用,適合使用的場景:

  • merge標籤最好是來替代FrameLayout;
  • 佈局方向一致的LinearLayout,比如當前父佈局LinearLayout的佈局方向是垂直的,包含的子佈局LinearLayout的佈局方向也是垂直的,則可以用merge標籤來替換子佈局LinearLayout;

4.3使用ViewStub來提高載入速度

使用場景:

一個很常見的開發場景就是我們想要一個佈局時,並不是所有的控制元件都需要顯示出來,而是顯示出一部分,對於這種情況,我們一般採用的方法就是使用View的GONE和INVISIBLE,但是這種方法效率不高,雖然是達到了隱藏的目的,但是仍在佈局當中,系統仍然會解析它們,我們可以用ViewStub來解決這一問題。

ViewStub的優勢

ViewStub是輕量級的View,不可見並且不佔佈局位置。當ViewStub呼叫inflate方法或者設定可見時,系統會載入ViewStub指定的佈局,然後將這個佈局新增到ViewStub中,在對ViewStub呼叫inflate方法或者設定可見之前,它是不佔佈局空間和系統資源的,它主要的目的就是為目標檢視佔用一個位置。因此,使用ViewStub可以提高介面初始化的效能,從而提高介面的載入速度。

使用

ViewStub的內容佈局檔案title_bar

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="40dp">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:text="Back"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="Title"/>
</RelativeLayout>

ViewStub所在的佈局檔案

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    android:orientation="vertical">

    <ViewStub
        android:id="@+id/vs"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout="@layout/title_bar"/>

</LinearLayout>

使用程式碼

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ViewStub vs = findViewById(R.id.vs);
        //vs.inflate();
        vs.setVisibility(View.VISIBLE);
    }

要注意的點

  1. ViewStub只能載入一次,載入後ViewStub物件會被置為空,這樣當ViewStub引用的佈局被載入後,就不能用ViewStub來控制引用的佈局了。因此,如果一個控制元件需要不斷的顯示和隱藏,還是要使用View的Visibility屬性。
  2. ViewStub不能巢狀Merge標籤。
  3. 上面的inflate和setVisiblity方法都可以。

4.4clipRect的使用

我們可以通過canvas.clipRect()來 幫助系統識別那些可見的區域。這個方法可以指定一塊矩形區域,只有在這個區域內才會被繪製,其他的區域會被忽視。這個API可以很好的幫助那些有多組重疊 元件的自定義View來控制顯示的區域。同時clipRect方法還可以幫助節約CPU與GPU資源,在clipRect區域之外的繪製指令都不會被執行,那些部分內容在矩形區域內的元件,仍然會得到繪製。

4.5非圖片Drawable的使用

使用場景:

在一些View的背景為純色或者已知漸變色的時候我們儘量用非圖片Drawable代替切圖,這樣帶來的好處是可以減小Apk的大小。

使用方法:

  1. 作為View的純色背景(使用shape);
  2. 作為點選變色Button的純色背景(selecter);

相關推薦

App效能優化View優化2——UI問題的解決

一.概況 上一篇中App效能優化之View優化(1)——UI問題的檢測主要講的是我們在寫完程式碼之後,如何發現程式碼中的問題。從問題中提取經驗,規範好自己之後的程式碼編寫,本文就是講如何規範的進行UI關聯程式碼的書寫。 二.主要的點 View控制元件

深度學習PyTorch實戰2——神經網路模型搭建和引數優化

  上一篇部落格先搭建了基礎環境,並熟悉了基礎知識,本節基於此,再進行深一步的學習。   接下來看看如何基於PyTorch深度學習框架用簡單快捷的方式搭建出複雜的神經網路模型,同時讓模型引數的優化方法趨於高效。如同使用PyTorch中的自動梯度方法一樣,在搭建複雜的神經網路模型的時候,我們也可以使用PyTor

資料庫redis篇2—— redis配置檔案,常用命令,效能測試工具

redis配置 如果你是找網上的其他教程來完成以上操作的話,相信你見過有的啟動命令是這樣的:   啟動命令帶了這個引數:redis.windows.conf,由於我測試環境是windows平臺,所以是這個,有的是redis.conf。顧名思義,redis.conf就是配置檔案,然後啟動時加

Android測量APP效能-分析和除錯 APK

分析和除錯預構建 APK Android Studio 3.0 允許您分析和除錯 APK,無需先從 Android Studio 專案構建這些 APK。 不過,您需要確保使用可除錯版本的 APK。 要開始除錯 APK,請在 Android Studio Welcome 歡迎螢幕中點選&nbs

Android ListView優化區域性重新整理更新非notifyDataSetChanged

在Android開發中我們經常會用到listview的資料和介面重新整理動作,我們每次可能會用到的都是Adapter.notifyDataSetChanged()方法。這個方法的原理是利用觀察者模式對我們的資料來源進行監聽,當我們的資料來源發生變化

MySQL優化索引原理

一,前言  ​ 上一篇內容說到了MySQL儲存引擎的相關內容,及資料型別的選擇優化。下面再來說說索引的內容,包括對B-Tree和B+Tree兩者的區別。 1.1,什麼是索引 ​ 索引是儲存引擎用於快速找到記錄的一種資料結構, 對效能的提升有很大的幫助,尤其當表中數量較大的情況下,索引正確的使用可以對效能提升幾

Web優化躬行記2——JavaScript

一、語言 1)慎用全域性變數   當變數暴露在全域性作用域中時,由於全域性作用域比較複雜,因此查詢會比較慢。   並且還有可能汙染window物件,覆蓋之前所賦的值,發生意想不到的錯誤。 0 == '' //true 0 == '0' //false 3)簡寫   簡寫的方式很多,此處只會列

Python+selenium測試報告2

def window win get hot 過程 https 書寫 screen 1 # -*- coding: utf-8 -*- 2 import HTMLTestReport 3 import HTMLTestRunner 4 import os 5 i

Scala 語言學習語言基礎2

err 實參 col res pre tom mom argument final 註: --------scala 中的任何數據都是對象 --------Scala 可以對數據類型進行自動推導,所以定義變量時可省去數據類型==> 數據類型

Linux學習路-Nginx2安裝及配置文件篇【23】---20180210

Nginx編譯 Nginx yum安裝 主配置文件分析 Core functionality分 一、Nginx的安裝方法及配置介紹1、yum安裝官方: http://nginx.org/packages/centos/7/x86_64/RPMSFedora-EPEL: http

Day2----Python學習路筆記2

cell 數據類型的轉換 編碼格式 python3 () shel 不能 索引 png 學習路線: Day1    Day2    Day3    Day4    Day5    ...待續  一、簡單回顧一下昨天的內容   1. 昨天了解到了一些編碼的知識 1.1

http協議版本差異2

大量 XML cti 技術 類型 版本 bsp 沒有 域名 —————————————HTTP1.0/HTTP1.1—————————————— 建立連接方面   HTTP/1.0 每次請求都需要建立新的TCP連接,連接不能復用。HTTP/1.1 新的請求可以在上次請求

MYSQL學習路42

資料表的基本操作2 (這裡的例子有用到前面1的) 2.檢視資料表結構 2.1查看錶基本結構語句DESCRIBE DESCRIBE/DESC可以檢視欄位的資訊,其中包括:欄位名、欄位資料型別、是否為主鍵、是否有預設值等。語法規則: DESCRIBE 表名;或者簡寫為:DESC 表名; 例:

目標檢測模型篇2【RRPN】

文章目錄 1. 前言 2. 實現 2.1 關鍵idea 2.2 模型結構 2.3 具體細節 1.Rotated Bounding Box Representation-旋轉矩形框的表示 2.Rotati

前端與移動開發vue-day12

Vue指令之v-on的縮寫和事件修飾符事件修飾符:.stop 阻止冒泡.prevent 阻止預設事件.capture 新增事件偵聽器時使用事件捕獲模式.self 只當事件在該元素本身(比如不是子元素)觸發時觸發回撥.once 事件只觸發一次 Vue指令之v-model和雙向資料繫結簡易計算器案例HTML 程

前端與移動開發vue-day22

全域性過濾器 // 定義一個全域性過濾器 Vue.filter('dataFormat', function (input, pattern = '') { var dt = new Date(input); // 獲取年月日 var y = dt.getFullYear(); v

Android四大元件2Service)

一、Service是android的四大元件,於activity最相似,於activity的區別在於,service一直執行在後臺,它沒有介面,所以絕不可能跑到前臺,一旦service被啟動起來,它就有它自己的額生命週期。service是四大元件,也是需要到androidManifest.xml檔案

前端與移動開發vue-day52

實現webpack的實時打包構建 由於每次重新修改程式碼之後,都需要手動執行webpack打包的命令,比較麻煩,所以使用webpack-dev-server來實現程式碼實時打包編譯,當修改程式碼之後,會自動進行打包構建。 執行cnpm i webpack-dev-server --save-dev安

前端與移動開發vue-day42

什麼是路由 後端路由:對於普通的網站,所有的超連結都是URL地址,所有的URL地址都對應伺服器上對應的資源; 前端路由:對於單頁面應用程式來說,主要通過URL中的hash(#號)來實現不同頁面之間的切換,同時,hash有一個特點:HTTP請求中不會包含hash相關的內容;所以,單頁面程式中的頁面跳轉

前端與移動開發vue-day32

【重點】為什麼元件中的data屬性必須定義為一個方法並返回一個物件 通過計數器案例演示 使用components屬性定義區域性子元件 元件例項定義方式: <script> // 建立 Vue 例項,得到 ViewModel var vm = new Vue({