多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > php開源 > 綜合技術 > Android的性能優化(上)

Android的性能優化(上)

來源:程序員人生   發布時間:2016-11-22 08:14:41 閱讀次數:3086次

1.Android UI的渲染機制

當我們感覺到的流暢畫面,需要的畫面幀數要到達40幀到60幀每秒。而1幀的時間大約是16.67ms,換句話說,在1000ms的時間內,16.67ms大約就是現實60幀畫面的單位時間。在Android系統中,系統是通過VSYNC信號觸發對UI的渲染的,如果系統每次渲染的事件都保持在16.67ms之內,那末我們看到的UI界面將是非常的流暢的,這也就需要我們將所有程序的邏輯都保證在16ms以內,如果不能在16ms內完成繪制,那末就將造成丟幀的現象。即當前該重繪的幀被未處理完成的邏輯阻塞,例如1次繪制任務耗時20ms,那末在16ms系統發出的VSYNC信號就沒法繪制,該幀就會被拋棄,等待下次信號擦次開始繪制,這就是畫面卡頓的緣由。

Android系統提供了檢測UI渲染時間的工具,在“開發者選項中”有“GPU顯現模式分析”,選擇“在屏幕上顯示為條形圖”,以下所示(本測試機為魅族,其他手機可能略有不同):
這里寫圖片描述

每個條形圖都包括有3部份,藍色部份表示丈量繪制Display List的時間,紅色代表的是OpenGL渲染Display List所需要的時間,黃色代表的是CPU等待GPU處理的時間,中間的綠色橫線代表的是VSYNC時間16ms,需要盡可能將所有條形圖都控制在這條綠線之下。

2.overDraw

overDraw表示的就是過度繪制,是指在1幀的時間內(16.67ms)像素被繪制了屢次,理論上1個像素每次只繪制1次是最優的,但是由于堆疊的布局致使1些像素會被屢次繪制,而每次繪制都會對應到CPU的1組繪圖命令和GPU的1些操作,造成CPU和GPU資源的浪費。在系統默許的繪制Activity的背景,如果再給布局繪制了堆疊的背景,那末默許Activity的背景就是無效的過度繪制。

在我們的“開發者選項”中有這樣1個檢測工具“調用GPU過度繪制”,激活該功能以后可以通過界面上的色彩來判斷overDraw的次數。
這里寫圖片描述
這個工具可以幫助我們檢測當前區域的繪制次數,從而優化界面繪圖層次,盡可能增大藍色的區域,減少紅色的區域。

3.優化布局層次

在Android中,系統對View進行丈量,布局和繪制時,都是通過對View數的遍歷來進行操作的。如果1個View樹的高度太高,就會嚴重影響到丈量,布局和繪制的速度,因此,優化布局的第1個方法就會是下降View樹的高度,Google也在API文檔中建議View樹的高度不宜超過10層。在現在的XML文件的根布局中,我們默許RelativeLayout來替換使用LineraLayout作為默許的根布局,其緣由就是通過扁平的RelativeLayout來下降LineraLayout嵌套所產生的布局樹的高度,從而提高UI的渲染速度。

1.使用 include 標簽重用Layout

在1個利用程序的界面上,為了保持風格的統1,很多界面都會存在共通的UI,比如所說Topbar,Bottombar,Actionbar等等,如果在每個界面上都進行賦值這1段共通的布局代碼,不但不利于后期代碼的保護,還會增加程序的冗余。這時候候就能夠使用include標簽來定義1這1個共通的UI。

<?xml version="1.0" encoding="utf⑻"?> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="0dp" android:layout_height="0dp" android:textSize="28sp" android:text="這是共通的UI界面" android:gravity="center"> </TextView>

在該共通的布局中,我將layout_width和layout_height設置為0dp,這樣就迫使調用者在使用時必須對控件的狂傲進行賦值,否者是沒法看見該控件的。

下1步就是如何使用該共通的UI布局了。只需要在使用該共通的UI布局文件中使用include標簽的layout屬性對這個共通的UI的ID的援用便可。

<?xml version="1.0" encoding="utf⑻"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <include layout="@layout/commen_ui" android:layout_width="match_parent" android:layout_height="wrap_content"/> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:textSize="20sp" android:text="你好你好你好"/> </LinearLayout>

這時候候如果我們要對布局中的屬性進行賦值,就要重新覆蓋某1項屬性,進行賦值便可。效果以下:
這里寫圖片描述

2. 使用ViewStub實現view的延遲加載

使用ViewStub標簽來實現對1個view的援用并且實現延遲加載。ViewStub是1個非常輕量級的組件,它不但不可視,而且大小為0,下面來演示如何使用ViewStub來進行實現延遲加載的目的。

首先創建1個布局,這個布局在初始化加載時是不需要顯示的,只有在某些情況下才需要進行顯示的,例如查看用戶信息的時候,只有點擊了某1個按鈕時,用戶詳細信息才顯示出來。
當運行程序后,我們發現ViewStub中的布局確切沒有顯示出來,那末要如何才能重新加載顯示的布局呢?
首先要通過findViewById()方法找到組件ViewStub。

mStub = (ViewStub) findViewById(R.id.vs_viewstub);
接下來就有兩種方式顯示這個view:
  1. VISIBLE
    通過調用ViewStub的setVisiblity()方法來顯示這個view.代碼以下:
mStub.setVisibility(View.VISIBLE);
  1. INFLATE
    通過調用ViewStub的inflate()方法來顯示這個view.代碼以下:
View inflate = mStub.inflate();

這兩種方式都是可以將ViewStub重新進行展開,顯示援用的布局,而唯1的區分在于就是inflate()可以返回援用的布局,從而可以通過View.findViewById()方法來找到對應的控件。

View inflate = mStub.inflate(); TextView textview = (TextView) inflate.findViewById(R.id.textview); textview.setText("我是點擊后加載的");

注意:不管只用那種方式,1旦ViewStub被設置可見或是inflate以后,ViewStub就不存在了,不能被反復的inflate,取而代之的就是被inflate的Layout,并將這個Layout的ID重新設置為ViewStub中通過android:inflateId屬性所指定的ID,這也就是為何兩次點擊以后會報錯的緣由:以下所示:

Caused by: java.lang.IllegalStateException: ViewStub must have a non-null ViewGroup viewParent

扼要說明View.GONE和ViewStub標簽的區分是甚么?共同點都是初始時都不會顯示,但是ViewStub標簽只會在顯示時才會去渲染全部布局,而View.GONE,在初始化布局樹的時候就已添加在布局樹文件中了,相比之下ViewStub的效力會更高。
以下圖所示:
這里寫圖片描述

4.hierarchyviewer.bat

hierarchyviewer.bat是沒法在真機上進行使用的,只能在摹擬器上使用或是原生的摹擬器上使用,也就是沒有加密的裝備上。固然真機上也是可以用的,可以到github上下載1個開源項目View Server,下面在摹擬器上使用hierarchyviewer.bat。
hierarchyviewer.bat位于sdk\tools目錄下,直接雙擊便可啟動,以下:
這里寫圖片描述

注意:我們在使用hierarchyviewer的時候,1定要是摹擬器是打開的,這樣才能在hierarchyviewer中看到我們要顯示的布局文件。
這里寫圖片描述

下面我們寫1個非常冗余的布局進行顯示文件,代碼以下所示:

<?xml version="1.0" encoding="utf⑻"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:text="你好啊啊 啊啊啊啊 啊" android:textColor="#efff0019" android:textSize="20sp"/> </LinearLayout> </LinearLayout> </LinearLayout>

這個布局文件是3層LinearLayout嵌套以后里面裝了1個button,很明顯這些LinearLayout都是冗余的,利用hierarchyviewer可以打開這個布局文件,以下圖所示:

這里寫圖片描述
通常情況下,我們只關注ID為content的Framlayout的分支,這也是setContentView()設置的內容,可以很明顯的看出在layout布局文件中(紅色布局),這3層LinearLayout沒有任何的分支,說明是冗余嵌套,可以直接去掉的。

當點擊其中1個view的時候,可以顯示view的繪制情況的,不過第1次點擊的時候各種顯示的事件都是n/a,需要點擊菜單中的Profile Node按鈕重新進行計算,才能回去到繪制信息。在系統的右下方會給出不同色彩的小圓點,用來表示繪制的效力,綠黃紅分別代表的是好中差的繪制效力。
這里寫圖片描述

生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 91亚洲欧美综合高清在线 | 国内国内在线精品视频 | 能看毛片的网址 | 国产人成午夜免费看 | 逼逼自拍| 夜夜躁日日躁狠狠 | 91福利院 | 在线精品日韩一区二区三区 | 日本一区二区视频 | 啪啪小视频网站 | 亚洲人和日本人jzz护士 | 欧美黑人xxxx猛牲大交 | 亚洲一级片免费 | 欧美性播放| 性做久久久久 | 中文字幕在线免费观看 | 免费一级欧美片片线观看 | 欧美日韩高清在线观看 | 精品国产一区二区三区久久 | 最近免费2019中文字幕大全 | 色吊丝一区二区 | 毛片色毛片18毛片美女 | 精品国产综合区久久久久久 | 免费爽视频 | 欧美一区二区三区网站 | 亚洲国产精品第一区二区 | 亚洲精品毛片久久久久久久 | 亚洲视频在线免费观看 | 国产成人永久免费视频 | 欧美黑人巨大xxxx猛交 | 亚洲网址 | 欧美成视频 | 成人国产免费 | 视频二区好吊色永久视频 | 亚洲欧美日产综合在线看 | 国产二区自拍 | 亚洲精品乱码久久久久久v 亚洲精品乱码久久久久久蜜桃 | 国产最新进精品视频 | 亚洲人网站| 欧美在线观看成人高清视频 | 日韩精品一区二区三区视频网 |