Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android App優化

Android App優化

編輯:關於Android編程

App的高性能應該是每個程序員追求的,當然也是用戶希望的。本篇文章來簡單介紹一下App優化的方式 1、UI優化 UI優化主要是提高UI的繪制效率,包括減少UI層次,提高初始化效率等。減少UI的繪制時間,能讓UI體驗更流暢,特別是低端手機上。 1.1 layout中ViewGroup的選擇 這個主要是針對LinearLayout和Relativelayout的選擇,LinearLayout的效率比RelativeLayout高,但是在相對復雜的布局下LinearLayout又容易造成比較多的UI層次影響效率。 \ 如果需要實現上圖的layout,是一種很常見的布局形式,應該如何布局的,這裡選擇兩種實現方式:
  • 外層使用一個橫向的LinearLayout再包裹一個RelativeLayout 實現 3+x層
  • 外層使用一個RelativeLayout ,先把Image位置確定,然後使用layout_align*等相對布局屬性實現 2+x層
以上第二種實現比第一種少了一層,如果是更復雜的布局,可能會出現相差很多層次的情況。因此,在選擇ViewGroup的時候盡量選擇合適的,簡單的布局,使用LinearLayout可能比較合適,復雜的UI布局,建議使用相對布局(RelativeLayout)。 1.2 使用include+merge include可以實現布局復用,使用很簡單。

  1. android:layout_width="match_parent"
  2. android:layout_height="wrap_content"
  3. android:gravity="center_horizontal"
  4. android:orientation="vertical"
  5. android:paddingBottom="@dimen/dd_dimen_40px" >
  6.  
  7. android:layout_width="match_parent"
  8. android:layout_height="wrap_content"
  9. layout="@layout/include_layout" />
  10. ......
  11.  
include_layout.xml布局代碼:

  1. android:layout_width="match_parent"
  2. android:layout_height="wrap_content" >
  3.  
  4. android:layout_width="48dp"
  5. android:layout_height="48dp"
  6. android:layout_alignParentRight="true"
  7. android:background="@android:color/transparent" />
  8.  
  9.  
開發過程中include_layout的布局可能會在很多不同的布局裡通過include標簽很方便的復用,但是有一種“壞味道”是,include可能增加了布局的層次,比如上面的代碼。省略其他來看xml代碼是3層布局,如果不使用include兩層就可以搞定,但是又不想放棄復用。這個時候可以使用merge來幫忙。 通過使用merge來修改上面的xml代碼,把include_layout.xml修改為:

  1.  
  2. android:layout_width="48dp"
  3. android:layout_height="48dp"
  4. android:layout_alignParentRight="true"
  5. android:background="@android:color/transparent" />
  6.  
  7.  
在復用的時候,merge中的Button會當做merge的父布局(RelativeLayout)的子布局來繪制了,這樣可以減少一層。當然如果merge的父布局是LiearLayout,這樣的布局會出問題,所以使用過程需要靈活搭配,選擇合適且正確的方式。 1.3 使用ViewStub延遲加載 ViewStub在布局初始化時候是大小為0,不被繪制的View,在需要加載的時候通過java代碼初始化它即可。在布局中有許多在一定條件下才展示View,可以使用ViewStub,初始化時減少UI的繪制時間,更快的展示出Activity。ViewStub中的View按需加載即可。 1.4、自定義View優化 自定義View的時候需要自己重寫onDraw方法,在onDraow中大量的計算,對象的創建都會對性能產生影響,所以需要最簡潔的重寫onDraw方法。 另一點就是在自定義View的時候,最好只繪制可見部分,被遮擋的部分可以繪制來提高效率。 1.5、其他
把不必要的背景設置為透明(減少過度繪制)。 2、內存優化   2.1、減少gc java中內存回收不受程序員控制的,在分配內存時內存不夠就會gc來回收一部分內存用來完成本次內存分配,gc會阻塞主線程,造成卡頓現象。

  1. dalvikvm: GC_FOR_ALLOC freed 573K, 6% free 37579K/39832K, paused 24ms, total 24ms
以上gc的log中paused的時間就是垃圾回收阻塞主線程的時間,這裡造成了24ms的卡頓。如果頻繁的發生gc,用戶體驗 會很差。如何減少自動gc呢?總結如下:
  • 避免頻繁創建對象
  • 對象在使用的時候創建
  • 使用對象池重復使用對象(例如 線程池、Message重復利用、ListView重復使用視圖)
  2.2、避免內存洩露 內存洩露會使得App的可使用內存原來越小,直至出現OOM。因此避免內存洩露可以使程序更流暢,也會很大程度上降低OOM出現的幾率。   2.2.1、內存洩露原因 出現內存洩露的原因主要有如下幾方面:
  • 訪問資源後未關閉。(流,Cursor等)
  • 靜態變量持有Activity或Service的引用。
  • 單例對象持有Activity或者Service的引用。
    例:單例類持有Activity或者Service的Context對象、單例類持有Activity的內部類、Activity作為監聽對象被單例類注冊等。
  • 永久對象持有Activity或者Service的引用。
    例:Handler作為非靜態內部類被Looper持有;ContentResolver注冊但未取消注冊,EventBus注冊但未取消注冊等。
  • 屬性動畫中的循環動畫沒有及時取消。
  2.2.2、檢測內存洩露 內存洩漏可以通過代碼或者工具來分析。
  • LeakCanary
LeakCanary使用很方便,在Application的onCreate方法添加 LeakCanary.install(this);

  1. public class MyApplication extends Application {
  2. @Override
  3. public void onCreate() {
  4. super.onCreate();
  5. LeakCanary.install(this);
  6. }
  7. }
當出現內存洩露時,通過下拉通知提醒: \leaktrace.png
  • Memory Analyzer Tool(MAT)
MAT是內存分析工具,可以幫助分析內存洩露。MAT可以打開標准的hprof文件來分析內存的使用情況。 首先需要生成hprof文件,這裡使用Android Studio中 Monitors中的Dump Java Heap,如下圖所示: \ 點擊圖標會自動執行一段兒時間生成hprof文件,studio會自動打開,這個文件存放在了上圖左邊的 Captures目錄下,選擇剛生成的文件右鍵選擇Export to standard .hprof生成一個可以被mat打開的標准hprof文件。 \ mat打開內存文件: \   可以選擇Dominator Tree: \ 第一行可以輸入正則來查詢有問題的類,然後選擇該行右鍵彈出選擇框(下圖是網上借來) \ 根據引用來分析內存洩露來源。當然這裡是MAT的簡單使用,“紙上得來終覺淺,絕知此事要躬行”,一定親自體驗以下才行。
  • StrickMode
StrickMode是系統Api,在debug模式下添加如下代碼就可以使用:

  1. StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectAll().penaltyLog().build());
  2. StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectAll().penaltyLog().build());
StrickMode分別設置了ThreadPolicy和VmPolicy可以在logcat中打印出StrickMode的log警告。包括主線程耗時信息和內存洩露的信息。 如何檢測一個Activity是否內存洩露呢?第一進入該Activity後退出,然後再次進入退出。如果出現StrickMode的紅色警告log,代表有內存洩露(也有沒有及時回收的時候,應該多試幾次) StrictMode: class com.demo.MainActivity; instances=2; limit=1   3、結束語 App優化是一個持續的過程,還可以通過選擇合適的數據結構、合適的算法來提高App的性能。  
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved