當前位置:首頁 » 安卓系統 » android布局的優化

android布局的優化

發布時間: 2022-09-07 13:26:08

1. 怎樣去優化安卓app的界面設計

第一點:了解你的目標客戶群的心態 1、做微任務的目標客戶群(如隨時隨地看看新聞,聽聽歌,看看電影,聊聊八卦之類): 這類的解決方案是設計的app最好是小而准,不要大而全。越全的功能應用,只能代表著這個應用在各方面的都很平庸 2、喜歡當工具來使用的目標客戶群:比如找地圖,看天氣,查數據等。 這類的解決方案是 我們盡最大努力的去滿足用戶的情景需求。做到極致和簡單。 3、無聊的客戶群,用來打發消磨時間的:無需求,漫無目的的 這類的解決方案是盡可能展示用戶感興趣的東西,幫助客戶來打發消磨時光。 第二點:APP原型圖的製作和設計討論 這個環節是必不可少的。需要根據設計需求認認真真的來畫畫原型圖。 常用的APP原型圖工具:移動APP原型設計神器 POP 、axure、Foreui等 第三點:APP視覺設計與設計要點 (1)大概設計板塊有APP啟動頁面設計,APP界面設計的尺寸規范,app圖標設計等 一般來說,手機屏幕是從上往下布局的,重要的信息會放在上方。但是在操作上,大部分人都是單手拿手機,常用的操作,要放在界面的下方。 另外還有一個原則,最小的觸摸單位,一般是44個像素。如果再小,你的拇指難以觸碰,或者容易引發誤操作。同時,也不要讓界面太擁擠。 所以,設計師必須用減法設計,這個過程需要花時間思考、簡化元素。 你必須記住:(1)隱藏設計或者減法設計 (2)分區或分類 (3)幫用戶做決策 (4)提高交互創新設計 (5)讓人有爽快感和新奇感 (6)在設計中浸入情感,把握用戶的心理。(談談如何進行產品設計以及產品情感化設計) 一位大師這樣說過「真正的簡約設計是:作品必須不斷的被簡化,一改再改,直到設計最終成形。」 2014年 APP設計風格趨向扁平化和卡片化。卡片,扁平化都會是移動app設計的趨勢!認為卡片設計確實同時兼具了「擬物」和「極簡」2種優勢!

2. 如何優化android xml布局

應該是布局方面的問題吧,在xml文件的ImageView有個scaleType屬性應該可以解決你的問題 android:scaleType是控制圖片如何resized/moved來匹對ImageView的size。 ImageView.ScaleType / android:scaleType值的意義區別: CENTER /center 按圖片的原來size居中顯示,當圖片長/寬超過View的長/寬,則截取圖片的居中部分顯示 CENTER_CROP / centerCrop 按比例擴大圖片的size居中顯示,使得圖片長(寬)等於或大於View的長(寬) CENTER_INSIDE / centerInside 將圖片的內容完整居中顯示,通過按比例縮小或原來的size使得圖片長/寬等於或小於View的長/寬 FIT_CENTER / fitCenter 把圖片按比例擴大/縮小到View的寬度,居中顯示 FIT_END / fitEnd 把圖片按比例擴大/縮小到View的寬度,顯示在View的下部分...

3. Android啟動優化概述

Android啟動應用, 按 官方說法 分為冷啟動, 溫啟動和熱啟動.
具體的定義可以看官方文檔, 簡單地說

一般我們只需要關注冷啟動即可.

要想啟動快, 硬體性能必然有影響, 在硬體一定的前提下, 我們要盡量 降低啟動應用時CPU的負載 , 讓CPU有更多的算力投入到啟動流程中:

在做好一些基本原則後, 接著看具體的流程優化點

在應用進程創建後, 首先必然是載入類, 此時一些靜態變數就會初始化了, 因此我們應該

類載入完畢後就是創建 Application 實例了, 因此我們應該

之後會先創建 ContentProvider 和執行 ContentProvider.onCreate() , 因此我們應該

跟接著就會執行 Application.onCreate() 等方法, 因此我們應該

接著就進入 Activity 環節.
同樣第一步會是創建實例, 因此我們應該

在 Activity 進程生命周期後, 第一步就是渲染(inflate)布局, 我們應該

在應用啟動的瞬間, 系統服務會先展示一個空白窗口, 等待應用第一幀繪制完畢後, 再從該窗口切換到應用, 如果啟動耗時較長, 就會明顯看到白屏, 對於這一點, 常見的操作有

可以使用IdleHandler, 在主線程空閑時再執行某些不重要的操作

實際上非同步初始化只是不阻塞主線程, 但是子線程一樣會佔用CPU資源, 讓主線程的執行時間變少, 所以不應該盲目地將所有工作放到子線程.

優化做到最後, 就是在系統流程上做文章了

原理是將啟動時載入的類放到主dex,提升了這些類的內聚,讓更多的類滿足pre-verify的條件,在安裝時就做了校驗和優化,以減少首次載入的耗時,從而優化冷啟動耗時。
Redex 初探與 Interdex:Andorid 冷啟動優化

應用啟動過程中會從apk壓縮包中讀取文件, 該優化的原理是利用Linux中的Pagecache機制, 讓啟動過程會用到的文件盡可能進入緩存中, 減少磁碟IO次數
支付寶 App 構建優化解析:通過安裝包重排布優化 Android 端啟動性能

在Dalvik VM(Android5.0以前)載入類的時候會有一個類校驗過程, 它需要校驗方法的每一個指令, 是一個比較耗時的過程, 可以通過Hook去掉類載入過程中的類驗證過程. 不過對於ART(Android5.0之後)來說, 這個過程在安裝時已經做了, 所以用處不大.

不進入冷啟動, 就不用優化了~

這個Android Studio自帶的工具, 可以看到啟動過程中詳細的方法執行流程, 但是採集數據本身會影響方法執行, 所以不能准確判斷每個方法的耗時, 但是仍可以判斷哪個方法相對來說耗時.

這個工具的好處是可以自定義事件, 可以指定需要採集的數據集, 可以看到線程間的狀態等.

啟動優化的一個關鍵點在於定義啟動結束的點, 以及如何測量啟動時間.

在Android4.4以上, 系統進程會提供一個類似 ActivityManager: Displayed ***: +3s534ms 的日誌, 表示從啟動進程到首次繪制完畢所用的時間.

應用可以在任何時候調用該方法, 觸發系統列印類似 system_process I/ActivityManager: Fully drawn {package}/.MainActivity: +1s54ms 的日誌

應用可以通過 ViewTreeObserver 來監聽繪制前回調來判斷第一幀的繪制時機, 或者直接在控制項樹的末尾加一個簡單的View, 它 onDraw 調用時即表示頁面(差不多)繪制完畢.

應用啟動過程可以參考 Android Vitals Series' Articles 系列文章

4. 怎樣android的布局優化載入

下面介紹幾種切實有效的方式:

  1. merge

    顧名思義,就是合並、融合的意思。使用它可以有效的將某些符合條件的多餘的層級優化掉。使用merge的場合主要有兩處:

    (1)自定義View中使用,父元素盡量是FrameLayout,當然如果父元素是其他布局,而且不是太復雜的情況下也是可以使用的

    (2)Activity中的整體布局,根元素需要是FrameLayout

  2. ViewStub

    (1)ViewStub只能Inflate一次,之後ViewStub對象會被置為空。按句話說,某個被ViewStub指定的布局被Inflate後,就不能夠再通過ViewStub來控制它了。所以它不適用 於需要按需顯示隱藏的情況。
    (2)ViewStub只能用來Inflate一個布局文件,而不是某個具體的View,當然也可以把View寫在某個布局文件中。如果想操作一個具體的view,還是使用visibility屬性吧。
    (3) VIewStub中不能嵌套merge標簽。(前面好像說過)
    不過這些確定都無傷大雅,我們還是能夠用ViewStub來做很多事情。

  3. include

    製造這個標簽純碎是為了布局重用,在項目中通常會存在一些布局公用的部分,比如自義標題,我們不需要把一份代碼Ctrl C, Ctrl V的到處都是,嚴重違背程序簡潔化、模塊兒化的設計思想

5. Android布局優化的幾種方式

1. include/merge

布局優化中常常用到include/merge標簽,include的含義類似C代碼中的include,意思是直接把指定布局片段包含進當前的布局文件。include適用於多個布局文件中存在相同的xml片段,比如說相同的標題欄、相同的廣告欄、相同的進度欄等等。

2. ViewStub

在一個頁面上根據不同條件展示不同的控制項,我們常常會設置控制項的可視屬性,比如調用指定控制項的setVisibility方法,若需展示則設置View.VISIBLE,若需隱藏則設置View.GONE。不過gone的控制項只是看不到罷了,實際UI渲染時還是會被載入。要想事先不載入,在條件符合時才載入,就得用到標簽ViewStub。

3. style樣式

樣式在res/values/styles.xml中定義,它適用於下面幾種情況:
1、布局文件中存在多個具有相同風格的控制項,比如說統一的文本框TextView,都是白底黑字、中號字體、居中顯示,這時我們便可在styles.xml定義一種文本樣式,然後在各文本框處聲明它的style屬性。好處一個是減少了布局文件的大小,另一個是方便以後統一修改風格。

2、某些控制項在代碼中聲明時需要手工指定style,例如自定義對話框需要在構造函數中指定樣式;另一個例子是彈窗PopupWindow在設置伸縮動畫方法setAnimationStyle時需要指定動畫樣式。
3、定義頁面的主題風格,然後應用到Activity頁面。代碼中設置主題可通過「setTheme(R.style.)」完成,布局中設置可在AndroidManifest.xml的activity節點下添加theme屬性,如「android:theme=」@style/「」。

4. Theme主題

主題是一種特殊的樣式,主題專用於頁面,而樣式一般運用於控制項。主題定義一般放在themes.xml,樣式定義一般放在styles.xml。
Android定義了一些系統主題,完整定義的參見sdk自帶的themes.xml,常用的幾種說明如下:
Theme.NoTitleBar : 不顯示標題欄,即隱藏ActionBar
Theme.Light : 白色背景
Theme.Holo : 淺灰背景
Theme.Black : 黑色背景
Theme.Wallpaper : 壁紙
Theme.Translucent : 透明背景
Theme.Dialog : 對話框
Theme.Panel : 平板
Theme.InputMethod : 輸入法
Theme.SearchBar : 搜索框

6. android 性能優化有哪些辦法

性能優化的常用方法

主要內容包括布局優化,繪制優化,內存泄露優化,相應速度優化,ListView優化,Bitmap優化,線程優化等,下面主要給你舉了其中的幾個例子:

(1)布局優化

布局優化的思想很簡單,就是盡量減少布局文件的層級。

如何進行優化呢?首先刪除布局中無用的控制項和層級,其次有選擇地使用性能較低的ViewGroup,比如LinearLayout。如果布局中有的布局既可以用LinearLayout也可以用RelativeLayout,那就用LinearLayout,這是因為RelativeLayout比較復雜,他的布局過程花費更多的CPU時間。FrameLayout和LinearLayout一樣都是一種簡單高效的ViewGroup,因此可以考慮使用他們,但是很多時候,單純的通過一個LinearLayout或者FrameLayout無法實現產品的效果,需要通過嵌套的方式來完成,這種情況建議採用RelativeLayout,因為ViewGroup的嵌套就相當於增加了布局的層級,同樣會降低程序的性能。

布局優化的另一種手段是採用<include>標槍,<merge>標簽和ViewStub。<include>標簽主要用於布局重用,<merge>標簽一般和<include>配合使用,它可以減少布局的層級。而ViewStub則提供了按需載入功能,當需要時才將ViewStub中的布局載入到內存,這提高了程序的初始化效率。

(2)繪制方法

繪制優化是指View的onDraw方法避免執行大量的操作,這主要有兩方面。

首先,onDraw中不要創建新的布局對象,這是因為onDraw方法可能會被頻繁調用,這樣就會在一瞬間產生大量的臨時對象,這不僅佔用了過多的內存而且還會導致系統更加頻繁的gc,降低了程序的執行效率。

另一方面,onDraw方法中不要做耗時的任務,也不能執行成千上萬次循環操作,盡管每次循環都很輕量級,但是大量的循環仍然十分搶佔CPU的時間片,這會造成View的繪制過程不流暢。

(3)內存泄露優化

內存泄露在開發過程中是一個需要重視的問題,但是由於內存泄露問題對開發人員的經驗和開發意識要求比較高,因此這是開發人員最容易犯的錯誤之一。內存泄露的優化分為兩個方面,一方面是在開發過程中避免寫出內存泄露的代碼,另一方面通過一些分析工具比如MAT來找出潛在的內存泄露繼而解決。

關於性能優化的建議

1.避免黃健過多對象;

2.不要過多使用枚舉,枚舉佔用的內存空間比整型大一些。

3.常量使用staticfinal來修飾。

4.使用一些Android特有的數據結構,比如SpareArray和Pair等,他們都具有更好的性能。

5.適當使用軟引用和弱引用。

6.採用內存緩存和磁碟緩存

7.盡量採用靜態內部類,這樣可以避免潛在的內部類而導致的內存泄漏。

7. Android TextView使用及性能優化

TextView 是Android中最常用的控制項,在這里記錄下TextView 的用法;

在Android中可以使用系統自帶的4種字體:

在XML中使用 android:typeface="normal" 進行設置

將字體文件放到main/assets/fonts目錄下,使用Asset讀取字體後進行設置

使用 android:drawableLeft="@mipmap/ic_launcher" 可以設置一張圖片顯示在文字的上下左右,減少布局層級

使用Span能夠在一段TextView中設置不同顏色的字體,鏈接,圖片等內容

使用ClickableSpan 能夠設置一段文字的點擊事件

創建自己的MyClickableSpan:

之後使用SpannableStringBuilder來創建字元串,並使用setSpan來為字元串的一部分設置Span對象

其中setSpan()方法的最後一個參數標識有以下常量,這些常量標識著在 對SpannableStringBuilder進行insert時 添加的字元適用的規則:

Spanned.SPAN_EXCLUSIVE_EXCLUSIVE

Spanned.SPAN_EXCLUSIVE_INCLUSIVE

Spanned.SPAN_INCLUSIVE_EXCLUSIVE

Spanned.SPAN_INCLUSIVE_INCLUSIVE

前一個 EXCLUSIVE / INCLUSIVE 標識著在設置了Span的一段字元之前(緊挨著)插入字元時,被不被包含到Span范圍中, EXCLUSIVE 表示包含, INCLUSIVE 表示不包含;

第二個 EXCLUSIVE / INCLUSIVE 同理表示插入這段字元之後的效果;

ImageSpan用於在TextView中插入圖片,可以用來實現圖文混排

使用方法:

這樣實現的效果是文字與圖片底部進行對齊,如果需要圖片中線與文字中線對其,需要自己重寫ImageSpan

​ Android 中的TextView中存在著很多EditText中的特性,在setText()方法中會涉及到很多Span相關的操作,比如設置TextWatcher,重新構造Spannable等操作,在我們僅僅顯示靜態文本的時候這些操作都是沒有必要的(通過使用普通的TextView進行Debug來驗證普通的TextView的確是Span的);

​ 在大量顯示靜態文本的時候就可以通過StaticLayout來計算出TextView的布局信息,這項工作可以放到非UI線程來進行,能夠減少在setText()的時候UI線程的耗時,達到優化TextView性能的目的;

​ StaticLayout是TextView中用於顯示多行靜態文本的Layout,也是能夠支持SpannableString的,只是不能在Span變化之後重新Layout,所以在大部分場景下已經適用;

通過這個自定義的View來顯示Text,在onDraw()的時候直接使用layout來進行繪制,而設置需要顯示的文本則直接使用setLayout()來實現

使用下面給出的參考鏈接中的測試Demo在 ZTE A2017 Android7.1.1 高通820設備上,普通TextView在ListView中連續滾動的幀數是55幀,使用StaticLayout的結果為60幀

可以作為在APP使用CPU資源較多的情況下的優化手段

參考鏈接: TextView預渲染研究

在Android中,TextView的測量消耗了大量的時間,Android P中提供了PrecomputedText能夠將測量這個過程放到後台來執行,減輕對於UI線程的卡頓;

非Android P時,使用AppCompatTextView控制項,使用setTextFeature()方法來將文本的measure過程放到其他線程來執行,而不是直接將text應用於TextView;

在調用了這個方法之後如果對TextView進行邊距,文字大小等的設置都將會報錯;

Prefetch Text Layout in RecyclerView

PrecomputedTextCompat

在ListView中僅替換設置Text的方法時未測試出性能與普通方法有什麼優勢,猜測是ListView沒有在getView和顯示之間預留時間,

測試項目地址:

https://github.com/GavynZhang/PrecomuptedTextViewTest

8. android 布局優化使用什麼標簽

android 布局優化主要使用抽象布局標簽

(1) <include>標簽
include標簽常用於將布局中的公共部分提取出來供其他layout共用,以實現布局模塊化,這在布局編寫方便提供了大大的便利。
下面以在一個布局main.xml中用include引入另一個布局foot.xml為例。main.mxl代碼如下:

java<?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="match_parent" >

<ListView
android:id="@+id/simple_list_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="@dimen/dp_80" />

<include layout="@layout/foot.xml" />

</RelativeLayout>

<?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="match_parent" > <ListView android:id="@+id/simple_list_view" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginBottom="@dimen/dp_80" /> <include layout="@layout/foot.xml" /> </RelativeLayout>
其中include引入的foot.xml為公用的頁面底部,代碼如下:

Java<?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="match_parent" >

<Button
android:id="@+id/button"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_40"
android:layout_above="@+id/text"/>

<TextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_40"
android:layout_alignParentBottom="true"
android:text="@string/app_name" />

</RelativeLayout>
<?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="match_parent" > <Button android:id="@+id/button" android:layout_width="match_parent" android:layout_height="@dimen/dp_40" android:layout_above="@+id/text"/> <TextView android:id="@+id/text" android:layout_width="match_parent" android:layout_height="@dimen/dp_40" android:layout_alignParentBottom="true" android:text="@string/app_name" /> </RelativeLayout>

<include>標簽唯一需要的屬性是layout屬性,指定需要包含的布局文件。可以定義android:id和android:layout_*屬性來覆蓋被引入布局根節點的對應屬性值。注意重新定義android:id後,子布局的頂結點i就變化了。(2) <viewstub>標簽
viewstub標簽同include標簽一樣可以用來引入一個外部布局,不同的是,viewstub引入的布局默認不會擴張,即既不會佔用顯示也不會佔用位置,從而在解析layout時節省cpu和內存。
viewstub常用來引入那些默認不會顯示,只在特殊情況下顯示的布局,如進度布局、網路失敗顯示的刷新布局、信息出錯出現的提示布局等。
下面以在一個布局main.xml中加入網路錯誤時的提示頁面network_error.xml為例。main.mxl代碼如下:

Java<?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="match_parent" >

……
<ViewStub
android:id="@+id/network_error_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout="@layout/network_error" />

</RelativeLayout>
<?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="match_parent" > …… <ViewStub android:id="@+id/network_error_layout" android:layout_width="match_parent" android:layout_height="match_parent" android:layout="@layout/network_error" /> </RelativeLayout>

其中network_error.xml為只有在網路錯誤時才需要顯示的布局,默認不會被解析,示例代碼如下:

Java<?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="match_parent" >

<Button
android:id="@+id/network_setting"
android:layout_width="@dimen/dp_160"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:text="@string/network_setting" />

<Button
android:id="@+id/network_refresh"
android:layout_width="@dimen/dp_160"
android:layout_height="wrap_content"
android:layout_below="@+id/network_setting"
android:layout_centerHorizontal="true"
android:layout_marginTop="@dimen/dp_10"
android:text="@string/network_refresh" />

</RelativeLayout>
<?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="match_parent" > <Button android:id="@+id/network_setting" android:layout_width="@dimen/dp_160" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:text="@string/network_setting" /> <Button android:id="@+id/network_refresh" android:layout_width="@dimen/dp_160" android:layout_height="wrap_content" android:layout_below="@+id/network_setting" android:layout_centerHorizontal="true" android:layout_marginTop="@dimen/dp_10" android:text="@string/network_refresh" /> </RelativeLayout>

在java中通過(ViewStub)findViewById(id)找到ViewStub,通過stub.inflate()展開ViewStub,然後得到子View,如下:

Javaprivate View networkErrorView;

private void showNetError() {
// not repeated infalte
if (networkErrorView != null) {
networkErrorView.setVisibility(View.VISIBLE);
return;
}

ViewStub stub = (ViewStub)findViewById(R.id.network_error_layout);
networkErrorView = stub.inflate();
Button networkSetting = (Button)networkErrorView.findViewById(R.id.network_setting);
Button refresh = (Button)findViewById(R.id.network_refresh);
}

private void showNormal() {
if (networkErrorView != null) {
networkErrorView.setVisibility(View.GONE);
}
}
private View networkErrorView; private void showNetError() { // not repeated infalte if (networkErrorView != null) { networkErrorView.setVisibility(View.VISIBLE); return; } ViewStub stub = (ViewStub)findViewById(R.id.network_error_layout); networkErrorView = stub.inflate(); Button networkSetting = (Button)networkErrorView.findViewById(R.id.network_setting); Button refresh = (Button)findViewById(R.id.network_refresh);} private void showNormal() { if (networkErrorView != null) { networkErrorView.setVisibility(View.GONE); }}

在上面showNetError()中展開了ViewStub,同時我們對networkErrorView進行了保存,這樣下次不用繼續inflate。這就是後面第三部分提到的減少不必要的infalte。

viewstub標簽大部分屬性同include標簽類似。上面展開ViewStub部分代碼

JavaViewStub stub = (ViewStub)findViewById(R.id.network_error_layout);
networkErrorView = stub.inflate();
ViewStub stub = (ViewStub)findViewById(R.id.network_error_layout);networkErrorView = stub.inflate();
也可以寫成下面的形式

JavaView viewStub = findViewById(R.id.network_error_layout);
viewStub.setVisibility(View.VISIBLE); // ViewStub被展開後的布局所替換
networkErrorView = findViewById(R.id.network_error_layout); // 獲取展開後的布局
View viewStub = findViewById(R.id.network_error_layout);viewStub.setVisibility(View.VISIBLE); // ViewStub被展開後的布局所替換networkErrorView = findViewById(R.id.network_error_layout); // 獲取展開後的布局
效果一致,只是不用顯示的轉換為ViewStub。通過viewstub的原理我們可以知道將一個view設置為GONE不會被解析,從而提高layout解析速度,而VISIBLE和INVISIBLE這兩個可見性屬性會被正常解析。


9. 針對Android的性能優化集中哪些方面

一、概要:

本文主要以Android的渲染機制、UI優化、多線程的處理、緩存處理、電量優化以及代碼規范等幾方面來簡述Android的性能優化

二、渲染機制的優化:

大多數用戶感知到的卡頓等性能問題的最主要根源都是因為渲染性能。

Android系統每隔16ms發出VSYNC信號,觸發對UI進行渲染, 如果每次渲染都成功,這樣就能夠達到流暢的畫面所需要的60fps,為了能夠實現60fps,這意味著程序的大多數操作都必須在16ms內完成。

*關於JobScheler的更多知識可以參考http://hukai.me/android-training-course-in-chinese/background-jobs/scheling/index.html

七、代碼規范

1)for loop中不要聲明臨時變數,不到萬不得已不要在裡面寫try catch。

2)明白垃圾回收機制,避免頻繁GC,內存泄漏,OOM(有機會專門說)

3)合理使用數據類型,StringBuilder代替String,少用枚舉enum,少用父類聲明(List,Map)

4)如果你有頻繁的new線程,那最好通過線程池去execute它們,減少線程創建開銷。

5)你要知道單例的好處,並正確的使用它。

6)多用常量,少用顯式的"action_key",並維護一個常量類,別重復聲明這些常量。

7)如果可以,至少要弄懂設計模式中的策略模式,組合模式,裝飾模式,工廠模式,觀察者模式,這些能幫助你合理的解耦,即使需求頻繁變更,你也不用害怕牽一發而動全身。需求變更不可怕,可怕的是沒有在寫代碼之前做合理的設計。

8)View中設置緩存屬性.setDrawingCache為true.

9)cursor的使用。不過要注意管理好cursor,不要每次打開關閉cursor.因為打開關閉Cursor非常耗時。Cursor.require用於刷cursor.

10)採用SurfaceView在子線程刷新UI,避免手勢的處理和繪制在同一UI線程(普通View都這樣做)

11)採用JNI,將耗時間的處理放到c/c++層來處理

12)有些能用文件操作的,盡量採用文件操作,文件操作的速度比資料庫的操作要快10倍左右

13)懶載入和緩存機制。訪問網路的耗時操作啟動一個新線程來做,而不要再UI線程來做

14)如果方法用不到成員變數,可以把方法申明為static,性能會提高到15%到20%

15)避免使用getter/setter存取field,可以把field申明為public,直接訪問

16)私有內部類要訪問外部類的field或方法時,其成員變數不要用private,因為在編譯時會生成setter/getter,影響性能。可以把外部類的field或方法聲明為包訪問許可權

17)合理利用浮點數,浮點數比整型慢兩倍

18)針對ListView的性能優化,ListView的背景色與cacheColorHint設置相同顏色,可以提高滑動時的渲染性能。ListView中getView是性能是關鍵,這里要盡可能的優化。

getView方法中要重用view;getView方法中不能做復雜的邏輯計算,特別是資料庫操作,否則會嚴重影響滑動時的性能

19)不用new關鍵詞創建類的實例,用new關鍵詞創建類的實例時,構造函數鏈中的所有構造函數都會被自動調用。但如果一個對象實現了Cloneable介面,我們可以調用它的clone()方法。

clone()方法不會調用任何類構造函數。在使用設計模式(Design Pattern)的場合,如果用Factory模式創建對象,則改用clone()方法創建新的對象實例非常簡單。例如,下面是Factory模式的一個典型實現:

20)public static Credit getNewCredit() {
return new Credit();
}
改進後的代碼使用clone()方法,如下所示:
private static Credit BaseCredit = new Credit();
public static Credit getNewCredit() {
return (Credit) BaseCredit.clone();
}
上面的思路對於數組處理同樣很有用。

21)乘法和除法

考慮下面的代碼:

  • for (val = 0; val < 100000; val +=5) { alterX = val * 8; myResult = val * 2; }
    用移位操作替代乘法操作可以極大地提高性能。下面是修改後的代碼:
    for (val = 0; val < 100000; val += 5) { alterX = val << 3; myResult = val << 1; }

  • 22)ViewPager同時緩存page數最好為最小值3,如果過多,那麼第一次顯示時,ViewPager所初始化的pager就會很多,這樣pager累積渲染耗時就會增多,看起來就卡。

    23)每個pager應該只在顯示時才載入網路或資料庫(UserVisibleHint=true),最好不要預載入數據,以免造成浪費

    24)提高下載速度:要控制好同時下載的最大任務數,同時給InputStream再包一層緩沖流會更快(如BufferedInputStream)

    25)提供載入速度:讓服務端提供不同解析度的圖片才是最好的解決方案。還有合理使用內存緩存,使用開源的框架

    引用:Android性能優化的淺談

    10. android 開發之app都可以進行哪些優化

    1.在後台取消一些線程中的動作

    我們知道App運行過程中所有的操作都默認在主線程(UI線程)中進行的,這樣App的響應速度就會受到影響。會導致程序陷入卡頓、死掉甚至會發生系統錯誤。

    為 了加快響應速度,需要把費時的操作(比如網路請求、資料庫操作或者復雜的計算)從主線程移動到一個單獨的線程中。最高效的方式就是在類這一級完成 這項操作,可以使用AsyncTask或者IntentService來創建後台操作。如果選擇使用IntentService,它會在需要的時候啟動起 來,然後通過一個工作線程來處理請求(Intent)。

    使用IntentService時需要注意以下幾點限制:

    • 這個類不要給UI傳遞信息,如果要向用戶展示處理結果信息請用Activity;

    • 每次只能處理一個請求;

    • 每一個處理請求過程都不能中斷;

    2.保持響應不發生ANR

    從UI線程中移除費時操作這個方式還可以防止用戶操作出現系統不響應(ANR)對話框。需要做的就是繼承AsyncTask來創建一個後台工作線程,並實現doInBackground()方法。

    還有一種方式就是自己創建一個Thread類或者HandlerThread類。需要注意這樣也會使App變慢,因為默認的線程優先順序和主線程的優先順序是一樣的,除非你明確設定線程的優先順序。

    3.在線程中初始化查詢操作

    當查詢操作正在後台處理時,展示數據也不是即時的,但是你可以使用CursorLoader對象來加快速度,這個操作可以使Activity和用戶之間的互動不受影響。

    使用這個對象後,你的App會為ContentProvider初始化一個獨立的後台線程進行查詢,當查詢結束後就會給調用查詢的Activity返回結果。

    4.其它需要注意的方面

    • 使用StrictMode來檢查UI線程中可能潛在的費時操作;

    • 使用一些特殊的工具如Safe.ijiami、Systrace或者Traceview來尋找在你的應用中的瓶頸;

    • 用進度條向用戶展示操作進度;

    • 如果初始化操作很費時,請展示一個歡迎界面。

    優化設備的電池壽命

      如果應用很費電,請不要責怪用戶卸載了你的應用。對於電池使用來說,主要費電情況如下:

    • 更新數據時經常喚醒程序;

    • 用EDGE或者3G來傳遞數據;

    • 文本數據轉換,進行非JIT正則表達式操作。

    5.優化網路

    • 如果沒有網路連接,請讓你的應用跳過網路操作;只在有網路連接並且無漫遊的情況下更新數據;

    • 選擇兼容的數據格式,把含有文本數據和二進制數據的請求全部轉化成二進制數據格式請求;

    • 使用高效的轉換工具,多考慮使用流式轉換工具,少用樹形的轉換工具;

    • 為了更快的用戶體驗,請減少重復訪問伺服器的操作;

    • 如果可以的話,請使用framework的GZIP庫來壓縮文本數據以高效使用CPU資源。

    6.優化應用在前端的工作

    • 如果考慮使用wakelocks,盡量設置為最小的級別;

    • 為了防止潛在的bug導致的電量消耗,請明確指定超時時間;

    • 啟用 android:keepScreenOn屬性;

    • 除了系統的GC操作,多考慮手動回收Java對象,比如XmlPullParserFactory和BitmapFactory。還有正則表達式的Matcher.reset(newString)操作、StringBuilder.setLength(0)操作;

    • 要注意同步的問題,盡管在主線程中是安全的;

    • 在Listview中要多採用重復利用策略;

    • 如果允許的話多使用粗略的網路定位而不用GPS,對比一下GPS需要1mAh(25s * 140 mA),而一般網路只用0.1mAh(2s * 180mA);

    • 確保注銷GPS的位置更新操作,因為這個更新操作在onPause()中也是會繼續的。當所有的應用都注銷了這個操作,用戶可以在系統設置中重新啟用GPS而不浪費電量;

    • 請考慮在大量數理運算中使用低精度變數並在用DisplayMetrics進行DPI任務時緩存變數值;

    7.優化工作在前台的應用

    • 請確保service生命周期都是短暫的,因為每個進程都需要2MB的內存,而在前台程序需要內存時也會重新啟動;

    • 保持內存的使用量不要太大;

    • 如果要應用每30分鍾更新一次,請在設備處於喚醒狀態下進行;

    • Service在pull或者sleep狀態都是不好的,這就是為什麼在服務結束時要使用AlarmManager或者配置屬性stopSelf()的原因。

    8.其它注意事項

    • 在進行整體更新之前檢查電池的狀態和網路狀態,等待最好的狀態在進行大幅度裝換操作;

    • 讓用戶看到用電情況,比如更新周期,後台操作的時候;

    • 實現低內存佔用UI

    9.找到布局顯示問題

    當 我們為布局單獨創建UI的時候,就是在創建濫用內存的App,它在UI中會出現可惡的延時。要實現一個流暢的、低內存佔用的UI,第一步就是搜索 你的應用找出潛在的瓶頸布局。使用Safe.ijiami和Android SDK/tools/中自帶的Hierarchy Viewer Tool工具。

    還有一個很好的工具就是Lint,它會掃描應用的源碼去尋找可能存在的bug,並為控制項結果進行優化。

    10.解決問題

    如果布局顯示結果發現了問題,你可以考慮簡化布局結構。可以把LinearLayout類型轉化成RelativeLayout類型,降低布局的層級結構

    熱點內容
    上傳網頁用什麼伺服器 發布:2024-05-03 08:57:08 瀏覽:909
    掌握ftp伺服器的配置與管理 發布:2024-05-03 08:06:58 瀏覽:766
    伺服器搭建的函數 發布:2024-05-03 07:54:44 瀏覽:815
    php包含數組 發布:2024-05-03 07:53:51 瀏覽:702
    短暫記憶存儲信息是有限的 發布:2024-05-03 07:48:14 瀏覽:537
    java集合對象 發布:2024-05-03 07:32:13 瀏覽:916
    蘋果自帶腳本 發布:2024-05-03 07:16:04 瀏覽:569
    商城導航源碼 發布:2024-05-03 07:14:15 瀏覽:552
    shell腳本日誌輸出 發布:2024-05-03 06:31:04 瀏覽:713
    伺服器快捷方式是什麼意思 發布:2024-05-03 06:28:18 瀏覽:108