Android開發性能優化總結

Android性能調優包含html

  • 移動網絡優化
  • Java(Android)代碼優化
  • 佈局優化
  • 數據庫性能優化

參考連接 http://www.trinea.cn/android/android-traceview/android

本文主要針對代碼調優web

應用程序的性能問題體如今不少方面, 好比第一次啓動速度慢,或者進入某一界面速度慢;動畫執行過程不流暢,或者動畫執行卡頓時間長;ListView列表滑動過程當中卡頓,不流暢;應用程序自定義的某特定界面執行速度慢;響應某一用戶事件時長時間無響應(ANR);操做數據庫時,執行大量數據的增刪改查操做,執行速度慢;文件讀寫頻繁,緩存文件過大致使卡頓;應用長時間運行後,隨機出現卡頓現象。算法

以上的問題的緣由可能不僅一個,而且不少狀況下並非應用自己的問題,也有多是系統其餘層次有問題,只不過體如今應用層。因此開發人員在處理性能問題時,須要作的第一件事情就是判斷是不是應用自身引發的性能問題,而後再對症下藥;但有些時候應用自己邏輯正常,但因爲系統的硬件配置不足引發了異常,此時就要根據產品或項目需求,採起一些更加精準的方式優化性能,以彌補硬件配置的不足。數據庫

如下從幾個不一樣的角度總結一下應用程序性能優化的一些方法。編程

1、編程思想緩存

應用層的性能優化一般能夠從如下幾個方面考慮:安全

  1. 瞭解編程語言的編譯原理,使用高效編碼方式從語法上提升程序性能;
  2. 採用合理的數據結構和算法提升程序性能,這每每是決定程序性能的關鍵;
  3. 重視界面佈局優化;
  4. 採用多線程、緩存數據、延遲加載、提早加載等手段,解決嚴重的性能瓶頸;
  5. 合理配置虛擬機堆內存使用上限和使用率,減小垃圾回收頻率;
  6. 合理使用native代碼;
  7. 合理配置數據庫緩存類型和優化SQL語句加快讀取速度,使用事務加快寫入速度;
  8. 使用工具分析性能問題,找出性能瓶頸; 固然確定還有不少其餘的性能優化方法,此處僅列出一些常常會用到的方法。

2、編程技巧性能優化

(一)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退出時其對象自己沒法被銷燬,會形成內存溢出。

  1. 避免內部的Getters/Setters

面向對象設計中,字段訪問使用Getters/Setters一般是一個好的原則,可是在Android開發中限於硬件條件,除非字段須要被公開訪問,不然若是隻是有限範圍內的內部訪問(例如包內訪問)則不建議使用Getters/Setters。在開啓JIT時,直接訪問的速度比間接訪問要快7倍。

  1. 使用加強for循環

優先使用加強for循環一般狀況下會得到更高的效率;除了一種狀況,即對ArrayList進行遍歷時,使用普通的for循環效率要更高。

  1. 使用package代替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](https://my.oschina.net/u/561366)</item>  
 </style>

10.cursor 的使用。

要注意管理好cursor,不要每次打開關閉cursor.由於打開關閉Cursor很是耗時。 再也不使用的cursor要記得關閉(通常在finally語句塊執行)。 有一種狀況下,咱們不能直接將Cursor關閉掉,這就是在CursorAdapter中應用的狀況,可是注意,CursorAdapter在Acivity結束時並無自動的將Cursor關閉掉,所以,你須要在onDestroy函數中,手動關閉。

protected void onDestroy() { 
      if (mAdapter != null && mAdapter.getCurosr() != 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。 **

  1. 儘可能使用局部變量

調用方法時傳遞的參數以及在調用中建立的臨時變量都保存在棧(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().

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](https://my.oschina.net/u/1162528)
    protected void onDestroy() {
        if (webView!= null) {
            webView.destroy();
            webView= null;
        }
        super.onDestroy();
    }

2五、 使用ProGuard來剔除不須要的代碼

android { buildTypes { release { minifyEnabled true // 打包剔除無關代碼 shrinkResources true // 打包剔除無關資源圖片 proguardFiles getDefaultProguardFile('proguard-android.txt'), 'src/main/proguard-project.txt' signingConfig signingConfigs.debug } }

相關文章
相關標籤/搜索