安卓性能優(yōu)化方案_第1頁
安卓性能優(yōu)化方案_第2頁
安卓性能優(yōu)化方案_第3頁
安卓性能優(yōu)化方案_第4頁
全文預覽已結束

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領

文檔簡介

4/4安卓性能優(yōu)化方案隨著技術的發(fā)展,智能手機硬件配置越來越高,可是它和現(xiàn)在的PC相比,其運算能力,續(xù)航能力,存儲空間等都還是受到很大的限制,同時用戶對手機的體驗要求遠遠高于PC的桌面應用程序。以上理由,足以需要開發(fā)人員更加專心去實現(xiàn)和優(yōu)化你的代碼了。選擇合適的算法和數(shù)據(jù)結構永遠是開發(fā)人員最先應該考慮的事情。同時,我們應該時刻牢記,寫出高效代碼的兩條基本的原則:(1)不要做不必要的事;(2)不要分配不必要的內(nèi)存。

我從去年開始接觸Android開發(fā),以下結合自己的一點項目經(jīng)驗,同時參考了Google的優(yōu)化文檔和網(wǎng)上的諸多技術大牛給出的意見,整理出這份文檔。

1.內(nèi)存優(yōu)化

Android系統(tǒng)對每個軟件所能使用的RAM空間進行了限制(如:Nexusone對每個軟件的內(nèi)存限制是24M),同時Java語言本身比較消耗內(nèi)存,dalvik虛擬機也要占用一定的內(nèi)存空間,所以合理使用內(nèi)存,彰顯出一個程序員的素質(zhì)和技能。

1)了解JIT

即時編譯(Just-in-timeCompilation,JIT),又稱動態(tài)轉譯(DynamicTranslation),是一種通過在運行時將字節(jié)碼翻譯為機器碼,從而改善字節(jié)碼編譯語言性能的技術。即時編譯前期的兩個運行時理論是字節(jié)碼編譯和動態(tài)編譯。Android原來Dalvik虛擬機是作為一種解釋器實現(xiàn),新版

(Android2.2+)將換成JIT編譯器實現(xiàn)。性能測試顯示,在多項測試中新版本比舊版本提升了大約6倍。

詳細請參考http://./doc/2aa9be23856a561253d36f5d.html/cool_parkour/blog/item/2802b01586e22cd8a6ef3f6b.html

2)避免創(chuàng)建不必要的對象

就像世界上沒有免費的午餐,世界上也沒有免費的對象。雖然gc為每個線程都建立了臨時對象池,可以使創(chuàng)建對象的代價變得小一些,但是分配內(nèi)存永遠都比不分配內(nèi)存的代價大。如果你在用戶界面循環(huán)中分配對象內(nèi)存,就會引發(fā)周期性的垃圾回收,用戶就會覺得界面像打嗝一樣一頓一頓的。所以,除非必要,應盡量避免盡力對象的實例。下面的例子將幫助你理解這條原則:

當你從用戶輸入的數(shù)據(jù)中截取一段字符串時,盡量使用substring函數(shù)取得原始數(shù)據(jù)的一個子串,而不是為子串另外建立一份拷貝。這樣你就有一個新的String對象,它與原始數(shù)據(jù)共享一個char數(shù)組。如果你有一個函數(shù)返回一個String對象,而你確切的知道這個字符串會被附加到一個StringBuffer,那么,請改變這個函數(shù)的參數(shù)和實現(xiàn)方式,直接把結果附加到StringBuffer中,而不要再建立一個短命的臨時對象。

一個更極端的例子是,把多維數(shù)組分成多個一維數(shù)組:

int數(shù)組比Integer數(shù)組好,這也概括了一個基本事實,兩個平行的int數(shù)組比(int,int)對象數(shù)組性能要好很多。同理,這試用于所有基本類型的組合。如果你想用一種容器存儲(Foo,Bar)元組,嘗試使用兩個單獨的Foo[]

數(shù)組和Bar[]數(shù)組,一定比(Foo,Bar)數(shù)組效率更高。(也有例外的情況,就是當你建立一個API,讓別人調(diào)用它的時候。這時候你要注重對API接口的設計而犧牲一點兒速度。當然在API的內(nèi)部,你仍要盡可能的提高代碼的效率)

總體來說,就是避免創(chuàng)建短命的臨時對象。減少對象的創(chuàng)建就能減少垃圾收集,進而減少對用戶體驗的影響。

3)靜態(tài)方法代替虛擬方法

如果不需要訪問某對象的字段,將方法設置為靜態(tài),調(diào)用會加速15%到20%。這也是一種好的做法,因為你可以從方法聲明中看出調(diào)用該方法不需要更新此對象的狀態(tài)。

4)避免內(nèi)部Getters/Setters

在源生語言像C++中,通常做法是用Getters(i=getCount())代替直接字段訪問(i=mCount)。這是C++中一個好的習慣,因為編譯器會內(nèi)聯(lián)這些訪問,并且如果需要約束或者調(diào)試這些域的訪問,你可以在任何時間添加代碼。而在Android中,這不是一個好的做法。虛方法調(diào)用的代價比直接字段訪問高昂許多。通常根據(jù)面向?qū)ο笳Z言的實踐,在公共接口中使用Getters和Setters是有道理的,但在一個字段經(jīng)常被訪問的類中宜采用直接訪問。無JIT時,直接字段訪問大約比調(diào)用getter訪問快3倍。有JIT時(直接訪問字段開銷等同于局部變量訪問),要快7倍。

5)將成員緩存到本地

訪問成員變量比訪問本地變量慢得多,下面一段代碼:

[java]viewplaincopy

1.for(inti=0;i優(yōu)化布局層數(shù);采用來共享布局。

vii.將Acitivity中的Window的背景圖設置為空。getWindow().setBackgroundDrawable(null);android的默認背景是不是為空。

viii.View中設置緩存屬性.setDrawingCache為true。

3.網(wǎng)絡優(yōu)化

1)避免頻繁網(wǎng)絡請求

訪問server端時,建立連接本身比傳輸需要跟多的時間,如非必要,不要將一交互可以做的事情分成多次交互(這需要與Server端協(xié)調(diào)好)。有效管理Service后臺服務就相當于一個持續(xù)運行的Acitivity,如果開發(fā)的程序后臺都會一個service不停的去服務器上更新數(shù)據(jù),在不更新數(shù)據(jù)的時候就讓它sleep,這種方式是非常耗電的,通常情況下,可以使用AlarmManager來定時啟動服務。如下所示,第30分鐘執(zhí)行一次。

[java]viewplaincopy

1.AlarmManageralarmManager=(AlarmManager)context.getSystemServic

e(Context.ALARM_SERVICE);

2.Intentintent=newIntent(context,MyService.class);

3.PendingIntentpendingIntent=PendingIntent.getService(context,0,inten

t,0);

4.longinterval=DateUtils.MINUTE_IN_MILLIS*30;

5.longfirstWake=System.currentTimeMillis()+interval;

6.am.setRepeating(AlarmManager.RTC,firstWake,interval,pendingInten

t);

2)數(shù)據(jù)壓縮

傳輸數(shù)據(jù)經(jīng)過壓縮目前大部門網(wǎng)站都支持GZIP壓縮,所以在進行大數(shù)據(jù)量下載時,盡量使用GZIP方式下載,可以減少網(wǎng)絡流量,一般是壓縮前數(shù)據(jù)大小的30%左右。

[java]viewplaincopy

1.HttpGetrequest=newHttpGet("http://./doc/2aa9be23856a561253d36f5d.html/gzipcontent");

2.HttpResponseresp=newDefaultHttpClient().execute(request);

3.HttpEntityentity=response.getEntity();

4.InputStreamcompressed=entity.getContent();

5.InputStreamrawData=newGZIPInputStream(compressed);

3)使用線程池

線程池,分為核心線程池和普通線程池,下載圖片等耗時任務放置在普通線程池,避免耗時任務阻塞線程池后,導致所有異步任務都必須等待。

4)選擇合適的數(shù)據(jù)格式傳輸形式

其中TreeParse是DOM解析Event/Stream是SAX方式解析。

很明顯,使用流的方式解析效率要高一些,因為DOM解析是在對整個文檔讀取完后,再根據(jù)節(jié)點層次等再組織起來。而流的方式是邊讀取數(shù)據(jù)邊解析,數(shù)據(jù)讀取完后,解析也就完畢了。在數(shù)據(jù)格式方面,JSON和Protobuf效率明顯比XML好很多,XML和JSON大家都很熟悉。

從上面的圖中可以得出結論就是盡量使用SAX等邊讀取邊解析的方式來解析數(shù)據(jù),針對移動設備,最好能使用JSON之類的輕量級數(shù)據(jù)格式為佳。

1)其他

設置連接超時時間和響應超時時間。Http請求按照業(yè)務需求,分為是否可以緩存和不可緩存,那么在無網(wǎng)絡的環(huán)境中,仍然通過緩存的HttpResponse瀏覽部分數(shù)據(jù),實現(xiàn)離線閱讀。

2.數(shù)據(jù)庫相關

1)相對于封裝過的ContentProvider而言,使用原始SQL語句執(zhí)行效率高,比如使用方法rawQuery、execSQL的執(zhí)行效率比較高。

2)對于需要一次性修改多個數(shù)據(jù)時,可以考慮使用SQLite的事務方式批量處理。

3)批量插入多行數(shù)據(jù)使用InsertHelper或者bulkInsert方法

4)有些能用文件操作的,盡量采用文件操作,文件操作的速度比數(shù)據(jù)庫的操作要快10倍左右。

3.性能測試

對于Android平臺上軟件的性能測試可以通過以下幾種方法來分析效率瓶頸,目前Google在Android軟件開發(fā)過程中已經(jīng)引入了多種測試工具包,比如Unit測試工程,調(diào)試類,還有模擬器的DevTools都可以直接反應執(zhí)行性能。

1)在模擬器上的DevTools可以激活屏幕顯示當前的FPS,CPU使用率,可以幫助我們測試一些3D圖形界面的性能。

2)一般涉及到網(wǎng)絡應用的程序,在效率上和網(wǎng)速有很多關系,這里需要多次的調(diào)試才能實際了解。

3)對于邏輯算法的效率執(zhí)行,我們使用Android上最普遍的,計算執(zhí)行時間來查看:

[java]viewplaincopy

1.longstart=System.currentTimeMillis();

2.//dosomething

3.longduration=System.currentTimeMillis()-start;

最終duration保存著實際處理該方法需要的毫秒數(shù)。

4)gc效率跟蹤,如果你執(zhí)行的應用比較簡單,可以在DDMS中查看下Logcat的VM釋放內(nèi)存情況,大概模擬下那些地方可以緩存數(shù)據(jù)或改進算法的。

5)線程的使用和同步,Android平臺上給我們提供了豐富的多任務同步方法,但在深層上并沒有過多的比如自旋鎖等高級應用,不過對于Service和appWidget而言,他們實際的產(chǎn)品中都應該以多線程的方式處理,以釋放CPU時間,對于線程和堆內(nèi)存的查看這些都可以在DDMS中看到。

6)利用traceview和monkey等工具測試應用。

7)利用layoutopt和ninepatch等工具優(yōu)化視圖。

4.結束語

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論