Android開發效能最佳化總結(一)

來源:互聯網
上載者:User

標籤:anr   關閉   角度   map   精準   安全   佔用   對象引用   它的   

  安卓開發應用首先要講究良好的使用者體驗,如果一款軟體卡頓現象嚴重,不流暢,經常崩潰,那麼將給使用者帶來極不良好的體驗,從而損失使用者。
  
  在實際開發和學習中,我總結了一下關於安卓效能的最佳化,供大家參考交流。
  
  應用程式的效能問題體現在很多方面, 比如第一次啟動速度慢,或者進入某一介面速度慢;動畫執行過程不流暢,或者動畫執行卡頓時間長;ListView列表滑動過程中卡頓,不流暢;應用程式自訂的某特定介面執行速度慢;響應某一使用者事件時間長度時間無響應(ANR);操作資料庫時,執行大量資料的增刪改查操作,執行速度慢;檔案讀寫頻繁,快取檔案過大導致卡頓;應用長時間運行後,隨機出現卡頓現象。
  
  以上的問題的原因可能不只一個,並且很多情況下並不是應用本身的問題,也有可能是系統其他層次有問題,只不過體現在應用程式層。所以開發人員在處理效能問題時,需要做的第一件事情就是判斷是否是應用自身引起的效能問題,然後再對症下藥;但有些時候應用本身邏輯正常,但由於系統的硬體設定不足引起了異常,此時就要根據產品或項目需求,採取一些更加精準的方式最佳化效能,以彌補硬體設定的不足。
  
  以下從幾個不同的角度總結一下應用程式效能最佳化的一些方法。
  
  一、編程思想
  
  應用程式層的效能最佳化通常可以從以下幾個方面考慮:
  
  1. 瞭解程式設計語言的編譯原理,使用高效編碼方式從文法上提高程式效能;
  
  2. 採用合理的資料結構和演算法提高程式效能,這往往是決定程式效能的關鍵;
  
  3. 重視介面布局最佳化;
  
  4. 採用多線程、快取資料、消極式載入、提前載入等手段,解決嚴重的效能瓶頸;
  
  5. 合理配置虛擬機器堆記憶體使用量上限和使用率,減少記憶體回收頻率;
  
  6. 合理使用native代碼;
  
  7. 合理設定資料庫緩衝類型和最佳化SQL語句加快讀取速度,使用事務加快寫入速度;
  
  7. 使用工具分析效能問題,找出效能瓶頸;
  
  當然肯定還有很多其他的效能最佳化方法,此處僅列出一些經常會用到的方法。
  
  二、編程技巧
  
  (一)Performance Tips (For Java)
  
  Google官網上有一些關於應用程式效能提升的技巧,之前公司內也有很多總結提到過,在此簡單羅列一下,詳細內容可以從官網擷取。
  
  http://developer.android.com/training/articles/perf-tips.html
  
  需要說明的是,文章列出的最佳化技巧主要是一些微小的效能提升,決定程式整體效能的仍然取決於程式的商務邏輯設計、代碼的資料結構和演算法。研發人員需要將這些最佳化技巧應用到平時的編碼過程中,積少成多,也會對效能有很大的影響。
  
  寫出高效的代碼需要遵循兩條原則:
  
  不執行不必要的操作;
  
  不分配不必要的記憶體;
  
  兩條原則分別針對CPU和記憶體,完成必要操作的前提下儘可能的節省CPU和記憶體資源,自然執行效率要高。單純這樣說聽起來很虛,畢竟沒有一個統一的標準判斷什麼是必要和不必要的,需要結合具體情況具體分析了。
  
  1. 避免建立不必要的對象
  
  建立太多的對象會造成效能低下,這誰都知道,可是為什麼呢?首先分配記憶體本身需要時間,其次虛擬機器運行時堆記憶體使用量量是有上限的,當使用量到達一定程度時會觸發記憶體回收,記憶體回收會使得線程甚至是整個進程暫停運行。可想而知,如果有對象頻繁的建立和銷毀,或者記憶體使用量率很高,就會造成應用程式嚴重卡頓。
  
  2.合理使用static成員
  
  主要有三點需要掌握:
  
  如果一個方法不需要操作運行時的動態變數和方法,那麼可以將方法設定為static的。
  
  常量欄位要聲明為“static final”,因為這樣常量會被存放在dex檔案的靜態欄位初始化器中被直接存取,否則在運行時需要通過編譯時間自動產生的一些函數來初始化。此規則只對基本類型和String類型有效。
  
  不要將視圖控制項聲明為static,因為View對象會引用Activity對象,當Activity退出時其對象本身無法被銷毀,會造成記憶體溢出。
  
  3. 避免內部的Getters/Setters
  
  物件導向設計中,欄位訪問使用Getters/Setters通常是一個好的原則,但是在Android開發中限於硬體條件,除非欄位需要被公開訪問,否則如果只是有限範圍內的內部訪問(例如包內訪問)則不建議使用Getters/Setters。在開啟JIT時,直接存取的速度比間接訪問要快7倍。
  
  4. 使用增強for迴圈
  
  優先使用增強for迴圈通常情況下會獲得更高的效率;除了一種情況,即對ArrayList進行遍曆時,使用普通的for迴圈效率要更高。
  
  5. 使用public代替private以便私人內部類高效訪問外部類成員
  
  私人內部類的方法訪問外部類的私人成員變數和方法,在文法上是正確的,但是虛擬機器在運行時並不是直接存取的,而是在編譯時間會在外部類中自動產生一些包層級的靜態方法,執行時內部類會調用這些靜態方法來訪問外部類的私人成員。這樣的話就多了一層方法調用,效能有所損耗。
  
  一種解決這個問題的方法就是將外部類的私人成員改為包層級的,這樣內部類就可以直接存取,當然前提是設計上可接受。
  
  6.合理使用浮點類型
  
  在Android裝置中浮點型大概比整型資料處理速度慢兩倍,所以如果整型可以解決的問題就不要用浮點型。
  
  另外,一些處理器有硬體乘法但是沒有除法,這種情況下除法和模數運算是用軟體實現的。為了提高效率,在寫運算式時可以考慮將一些除法操作直接改寫為乘法實現,例如將“x / 2”改寫為“x * 0.5”。
  
  7.採用<merge>最佳化布局層數。 採用<include>來共用布局。
  
  8.延時載入View. 採用ViewStub 避免一些不經常的視圖長期被引用,佔用記憶體.
  
  9.移除Activity預設背景,提升activity載入速度。
  
  如果確信在Activity中使用不透明的背景,那麼可以移除Activity的預設背景。
  
  在代碼中:getWindow().setBackgroundDrawable(null);
  
  也可以在styles樣式檔案中設定並在Manifest檔案中配置
  
  <style name="MyStyle" parent="AppTheme">
  
  <item name="android:windowNoTitle">true</item>
  
  <item name="android:windowBackground">@null</item>
  
  </style>
  
  10.cursor 的使用。
  
  要注意管理好cursor,不要每次開啟關閉cursor.因為開啟關閉Cursor非常耗時。
  
  不再使用的cursor要記得關閉(一般在finally語句塊執行)。
  
  有一種情況下,我們不能直接將Cursor關閉掉,這就是在CursorAdapter中應用的情況,但是注意,CursorAdapter在Acivity結束時並沒有自動的將Cursor關閉掉,因此,你需要在onDestroy函數中,手動關閉。
  
  protected void onDestroy() {
  
  if (mAdapter != null && mAdapter.getCurosr(www.furggw.com) != null) {
  
    mAdapter.getCursor().close();
  
  }
  
  super.onDestroy();
  
  11.廣播BroadCast動態註冊時,記得要在調用者生命週期結束時unregisterReceiver,防止記憶體流失。
  
  12.針對ListView的效能最佳化
  
  item儘可能的減少使用的控制項和布局的層次;背景色與cacheColorHint設定相同顏色;ListView中item的布局至關重要,必須儘可能的減少使用的控制項,布局。RelativeLayout是絕對的利器,通過它可以減少布局的層次。同時要儘可能的複用控制項,這樣可以減少ListView的記憶體使用量,減少滑動時GC次數。ListView的背景色與cacheColorHint設定相同顏色,可以提高滑動時的渲染效能。ListView中getView是效能是關鍵,這裡要儘可能的最佳化。getView方法中要重用view;getView方法中不能做複雜的邏輯計算,特別是資料庫操作,否則會嚴重影響滑動時的效能;ListView資料項目較多時考慮分頁載入。
  
  13.注意使用線程的同步機制(synchronized),防止多個線程同時訪問一個對象時發生異常。
  
  14.合理使用StringBuffer,StringBuilder,String
  
  在簡單的字串拼接中,String的效率是最高的,例如String s = “hello” + “world”;
  
  但大家這裡要注意的是,如果你的字串是來自另外的String對象的話,速度就沒那麼快了,例如:
  
  String str2 = “This is”;
  
  String str3 = “ a ”;
  
  String str4 = “ test”;
  
  String str1 = str2 +str3 + str4;
  
  這裡就要求使用StringBuilder了
  
  在單線程中,StringBuilder的效能要比StringBuffer高。多線程為了安全執行緒需要採用StringBuffer,因為它是同步的。常規下一般用StringBuilder。
  
  15. 盡量使用局部變數
  
  調用方法時傳遞的參數以及在調用中建立的臨時變數都儲存在棧(Stack)中,速度較快。其他變數,如靜態變數、執行個體變數等,都在堆(Heap)中建立,速度較慢。另外,依賴於具體的編譯器/JVM,局部變數還可能得到進一步最佳化。
  
  16.I/O流操作記得及時關閉流對象。
  
  17.使用IntentService代替Service
  
  IntentService和Service都是一個服務,區別在於IntentService使用隊列的方式將請求的Intent排入佇列,然後開啟一個worker thread(線程)來處理隊列中的Intent(在onHandleIntent方法中),對於非同步startService請求,IntentService會處理完成一個之後再處理第二個,每一個請求都會在一個單獨的worker thread中處理,不會阻塞應用程式的主線程,如果有耗時的操作與其在Service裡面開啟新線程還不如使用IntentService來處理耗時操作。
  
  18.使用Application Context代替Activity中的Context
  
  不要讓生命週期長的對象引用activity context,即保證引用activity的對象要與activity本身生命週期是一樣的
  
  對於生命週期長的對象,可以使用Application Context
  
  不要把Context對象設定為靜態。
  
  19.集合中的對象要及時清理
  
  我們通常把一些對象的引用加入到了集合中,當我們不需要該對象時,並沒有把它的引用從集合中清理掉,這樣這個集合就會越來越大。如果這個集合是static的話,那情況就更嚴重了。
  
  20.Bitmap的使用
  
  較大的Bitmap注意壓縮後再使用,載入高清大圖可以考慮BitmapRegionDecoder的使用,
  
  不再使用的Bitmap注意及時recycle(www.272345.cn ).
  
  21.巧妙的運用軟引用(SoftRefrence)
  
  有些時候,我們使用Bitmap後沒有保留對它的引用,因此就無法調用Recycle函數。這時候巧妙的運用軟引用,可以使Bitmap在記憶體快不足時得到有效釋放。有關Java引用機制的介紹可以看我的另一篇部落格:http://blog.csdn.net/gs12software/article/details/51051813
  
  22.盡量不要使用整張的大圖作為資源檔,盡量使用9path圖片
  
  應用表徵圖優先放在mipmap目錄下(AndroidStudio環境),其他資源圖,.9圖應該放在drawable-xxxx下,需要複製到手機sd卡上使用的應放在asset目錄
  
  23.瞭解並使用庫函數
  
  Java標準庫和Android Framework中包含了大量高效且健壯的庫函數,很多函數還採用了native實現,通常情況下比我們用Java實現同樣功能的代碼的效率要高很多。所以善於使用系統庫函數可以節省開發時間,並且也不容易出錯。
  
  24.關於WebView
  
  在Activity或者Fragment銷毀時記得把WebView也銷毀
  
  @Override
  
  protected void onDestroy() {
  
  if (webView!= null) {
  
  webView.destroy(www.huachenj157.com);
  
  webView= null;
  
  }
  
  super.onDestroy(www.furongpt.com);
  
  三、使用工具分析應用程式效能
  
  (這部分內容較多,詳情請看《Android開發效能最佳化總結(二)》。

Android開發效能最佳化總結(一)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.