Android調試優化篇

  爲了開發出商業級的應用程序,大規模的測試是不可避免的,同時爲了提高應用程序的運行速度,需要進行必要的優化。在Android中,提供了豐富的調試與優化工具供開發人員應用,主要包括模擬器和目標端等兩種場景下使用的工具。

1.Android調試

        軟件調試是一個伴隨軟件開發的必然過程,好的調試環境和工具可以提高開發的效率。在Android中,除了提供GDB調試外,還提供了DNSS、Logcat、Dmtracedump、DevTools、Procrank、Dumpsys等開發工具供開發者使用,其中DMSS包含了多個組件。

        當發生Android ANR錯誤時,錯誤信息會保存在\data\anr\traces.txt中,這有助於在無法實時查看日誌的情況下分析Bug。

        (1)Logcat日誌調試

                android.util.Log常用的方法有以下5個:Log.v()、Log.d()、Log.i()、Log.w()及Log.e(),其分別對應VERBOSE、DEBUG、INFO、WARN、ERROR等不同等級。

                開發者可以根據場景的不同選擇不同的方法。一般情況下,對於純粹的調試信息,筆者建議採用Log.d()方法。

                需要說明的是,android.util.Log僅適用於應用層,對於框架層的調試,需要使用android.util.slog類。

                C/C++依然支持log的輸出。

        (2)dmtracedump跟蹤

                dmtracedump是一個基於圖形界面的用法間調用關係的工具。在使用dmtracedump前,必須安裝Graphviz,在Linux下安裝Graphviz的方法如下:

                        #apt-get install graphviz

                dmtracedump的用法如下:

                        dmtracedump [-ho] [-s sortable] [-d trace-base-name] [-g outfile] <trace-base-name>

                在實際操作中,爲了分析函數間的調用關係,首先要在需要分析的方法中設置跟蹤的起始點和結束點,方法如下:

                        開始跟蹤:Debug.startMethodTracing("loadEvents");      //輸出文件爲loadEvents.trace

                        結束跟蹤:Debug.stopMethodTracing();

                程序運行結束後,即可在\sdcard下看到loadEvents.trace即可分析時間關係和方法調用關係。當然這是文本界面的,要通過圖形界面來顯示就要用到dmtracedump,方法如下:

                        #dmtracedump -g out.png clac.trace

                瀏覽out.png即可看到相關函數調用關係圖,其結點的格式如下:

                        <ref> callname (<inc-ma>,<exc-ms>,<numcalls>)

                上述格式中,ref表示編號,callname表示方法名,inc-ms表示調用事件,exc-ms表示執行時間,numcalls表示執行次數。

        (3)Dev Tools調試

                Dev Tools是Android特有的、幫組在物理設備上開發調試應用的工具,默認在SDK中存在。

                通過Dev Tools可以打開一些設備幫組調試的設置,如USB的設備等,還可以查看安裝包、啓動終端等,這些對開發者在物理設備上調試應用顯得十分有用。

        (4)屏幕截圖分析

                另一個簡單卻十分有用的工具是DDMS下的screen capture工具。通過它,開發者可以直接截圖,供自己或同事進行相應的分析,這在需要溝通的場景中十分有用。screen caption工具支持界面的手工刷新和旋轉,其保存圖片的格式爲PNG。

                目前screen capture工具對視頻播放尚無法提供有效的支持,這可能是由於視頻幀速率過快,而screen capture工具尚無法支持這麼高的幀速率導致的。

        (5)內存調試

                內存調試不僅限於C、C++等原生代碼,Java也同樣需要,在Android中,有多個工具如DDMS、Procrank、Dumpsys等可以獲取系統運行期的內存信息,這些信息十分有助於進行內存調試。

                1)DDMS內存調試

                         在Eclipse中集成的DMSS並沒有呈現出全部的DMSS能力,如果希望觀察系統更詳細的信息,可以直接啓動DK\tools\ddms。

                2)Dumpsys內存調試

                         通過Dumpsys可以進行很多分析,其分析內存的方法爲adb shell dumpsys meminfo。

                3)Procrank內存調試

                        另外,通過adb shell procrank也可以查看到進程佔用內存的情況,其中Uss(Unique Set Size)的大小代表屬於本進程正在使用的內存大小,這些內存在該進程被撤銷後,會被完全回收,Uss也是進行內存泄露觀察時的重點:Vss(Virtual Set Size)和Rss(Rsdident Set Size)表示共享庫的內存使用,但是由於共享庫的資源一般佔用比較大,因此會使進程自身創建引起的內存波動所佔比例減小;而Pss(Proportional Set Size)則按照比例進行共享內存分割。

                        通過間隔性地運行Procrank來觀察進程佔用Uss內存的變化,可以分析應用是否存在內存泄露。Procrank的代碼位於system\extras\procrank文件夾。Procrank的用法爲:

                                procrank [-W] [-v | -r| -p| -u| -h]

                        考慮到Android是基於Dalvik虛擬機的,垃圾回收並非實時的,故通過單個界面的單次啓動、關閉是無法確定內存是否泄露的。一個號的策略是重複執行某個界面的啓動、關閉,如果發現應用佔用的內存不斷上升,則可以判斷該界面存在內存泄露。

                4)Eclipse插件內存調試

                        在Eclipse中,有一個插件MAT(Memory Analyzer Tool)可以幫組分析Java層的內存泄露,其下載地址爲http://www.eclipse.org/mat/

                        MAT分析的是hprof文件,該文件中存放了進程的內存快照。下面是從終端獲取hprof文件的方法:

                                #adb shell

                                #ps                          //查看進程號

                                #chmod 777  /data/misc

                                #kill -10 PID                 //PID即進程號

                       這樣即可在\data\misc目錄下生成一個帶當前時間的hprof文件,但這個文件並不能直接被MAT讀取,開發者需藉助hprof-conv將hprof轉換爲MAT可以讀取的格式,然後纔可用MAT進行分析。hprof-conv的用法如下:

                                hprof-conv <infile><outfile>

2.Android佈局優化

        爲了實現精細的佈局,Android提供了兩個Android佈局優化,即Layoutopt和Hierarchyviewer。其中Layoutopt可以優化佈局,幫組開發者減少冗餘信息,而Hierarchyviewer則可直接調試用戶界面。

        (1)Layoutopy優化

                Layoutipt是一個優化佈局的工具,它可以幫組開發者分析採用的佈局是否合理,並給出修改意見,其用法是:

                        layoutopt <directories/files to analyze>

                具體方法如下:

                        layoutopt res/layout-land

                        layoutopt res/layout/main.xml

                Layoutopt可以指出有問題的代碼所在的位置和出問題的原因,還可以給出優化的建議。

        (2)Hierarchyviewer優化

                Hierarchyviewer允許開發者調試和優化用戶界面。通常Hierarchyviewer開發者可以清晰地看到當前設備的UI界面的實際佈局和控件屬性,這在複雜界面的調試中顯得非常有用,可以幫助開發者快速定位問題。當然出於安全性考慮,Hierachyviewer僅能優化debug模式的應用。

                發起Hierarchyviewer優化的步驟如下:

                        1)啓動物理設備或模擬器。

                        2)運行應用至欲優化的界面。

                        3)在終端啓動Hierarchyviewer(位於SDK的tools目錄下)。

                        4)選擇設備和Activity。

                Hierarchyviewer提供了兩個層次的分析界面,即視圖界面和像素界面。在Herarchyviewer的視圖界面中,開發者可以清晰地看到佈局文件的層次關係,針對特定的UI控件,開發者可以清晰地看到控件在屏幕上的位置以及各屬性的值。熟練使用Hierarchyviewer,可以加快UI調試效率。

3.Android測試

        Android提供的幾種測試工具可以幫組開發者最大限度地提升開發質量和應用程序的兼容性。這些測試工具中最重要的兩個爲Monkey壓力測試工具和CTS兼容性測試工具。

        (1)Monkey壓力測試

                Monkey工具可以模擬各種按鍵、觸屏、軌跡球、導航、Activity等事件。此工具用法如下:

                        adb shell monkey [option] <event-count>        //特定事件

                        adb shell monkey -p your.packege.name -v 50000        //50000隨機事件

                爲了使開發的應用程序具有一定的穩定度,在使用前建議進行Monkey壓力測試。需要注意的是,Monkey壓力測試僅能模擬系統事件監測應用中存在的語法Bug,對於深層次的語義Bug依然無能爲力,而且對於網絡功能,Monkey壓力測試也無法進行有效的測試。

                由於Monkey是通過加載特定Activity(category屬性需爲android.intent.category.LAUNCHER或android.intent.category.MONKEY)作爲程序入口來進行測試的,故在進行Monkey壓力測試時,容易形成孤島的Activity,爲了進行全面測試,需要爲其增加Intent過濾器。相應的參考實現如下:

                        <activity android:name="Hello">

                                <intent-filter>

                                        <action android:name="android.intent.action.MAIN"/>

                                        <category android:name="android.intent.category.MONKEY"/>

                               </intent-filter>

                        </activity>

                需要注意的是,如果只針對單個應用進行壓力測試,Monkey會阻止對其他包的調用,當然針對單個應用的壓力測試無法檢測應用間交互可能存在Bug。爲了測試系統內應用交互與衝突帶來的問題,可以針對系統進行Monkey壓力測試,方法如下:

                        #adb shell monkey -p -v 50000

                在進行Monkey壓力測試的過程中,Monkey會因爲應用奔潰、網絡超時及一些無法處理的異常而停止測試。建議在對網絡應用進行壓力測試時,忽略網絡超時的情況,方法如下:

                        #adb shell monkey -p your.package.name -v 50000 --ignore-timeouts

                如果希望忽略應用奔潰的情況,那麼可執行如下方法:

                        #adb shell monkey -p your.package.name -v 50000 --ignore-crashes

                在進行壓力測試時,如果發生異常情況,如系統奔潰,那麼Android會自動打印出相關的系統信息(如內存分配等)供開發者分析。

                另外,爲了更好地進行Monkey壓力測試,需要使外圍設備的配置保持和實際產品相同,如默認的鍵盤時QWERTY鍵盤(這對於沒有物理鍵盤的產品不適用)。

        (2)JUnit迴歸測試

                JUnit迴歸測試即白盒測試,通常用在單元測試場景中,如對非圖形界面的接口的測試,這在開發框架性代碼時非常有用。Android僅支持JUnit3,尚不支持JUnit4。

                在Android中,Google對JUnit進行了封裝,Android JUnit還支持圖形界面如Activity、View等的測試,甚至支持對圖形界面接口的功能壓力測試。Android JUnit的內容分主要分佈在android.text中,另外android.text.mock和android.text.suitebuilder也提供了一些輔助和支持。

                根據約束的不同,測試可以分爲SmallTest、MediumTest、LargeTest、AndroidOnly、SideEffect、UiThreadTest、BrokenTest、SmokeSuppress等。其中AndroidOnly、表示測試項僅適用於Android;SideEffect表示測試項具有副作用;UiThreadTest表示測試項在UI主線程中運行;BrokenTest表示測試項需要修復;Smoke表示測試項爲冒煙測試;Suppress表示該測試項不應出現在測試用例中。

                爲了進行JUnit迴歸測試,需要在Eclipse中創建Android Test Project,可通過執行File-New-Other-Android-Android Test Project命令完成,運行測試的方法爲右擊工程項,在彈出的菜單中執行run as-android JUnit Test命令,對於具有多個Instrumentation-TestRunner的測試工程,在執行測試時,應該先在工程的Run Configurations中指明InstrumentationTestRunner。測試完成後,會自動給出測試結論。在物理設備上藉助Dev Tools也可以做JUnit測試,當然,通過am命令也可以執行JUnit測試,不過這種方法比較繁瑣。

                1)JUnit測試的框架

                         Junit測試主要包括TestCase、Instrumentation等。爲了運行測試用例,必須將測試用例添加到TestSuite中,通過Instrumentation來管理。測試用例的繼承關係如下圖:

                                 

                        除了以上測試用例外,開發者還可以通過PerformanceTestCase執行性能測試。注意,ProviderTestCase和ActivityInstrumentationTestCase已經被拋棄,應慎用。

                        InstrumentationTestRunner主要通過AndroidTestRunner的支持被加載的。AndroidTestRunner的繼承關係如下圖所示:

                                

                        AndroidTestRunner繼承了TestListener接口,用來發起和結束測試,生成測試報告,其中發起運行測試的方法爲runTest(),這纔是JUnit測試的核心。

                2)JUnit測試的實現

                        通過JUnit進行迴歸測試,需要做如下幾方面的工作:

                                構建AndroidMainifest.xml配置文件。

                                制定InstrumentationTestRunner文件。

                                構建具體測試代碼。

                                如果是基於源代碼進行的測試,那麼還需要構建Android.mk文件。

                        (1)構建AndroidMainifest.xml配置文件

                                和普通工程類似的是,JUnit迴歸測試工程需要構建AndroidMainfest.xml配置文件;但和普通工程不同的是,JUnit迴歸測試工程沒有圖形界面,必須聲明要用到“android.test.runner"JAR包,聲明相應的Instrumentation TestRunner。在通過SDK創建測試工程時,AndroidMainfest.xml會自動生成,默認的InstrumentationTestRunner爲android.testRunner。在某些情況下,開發者需要定義InstrumentationTestRunner。下面是JUnit迴歸測試的AndroidMainfest.xml文件的實現:

                                         <mainfest xmlns:android="http://schemas.android.com/apk/res/android

                                                 package="com.android.calcutor2.tests">

                                                 <application>

                                                         <use-library android:name=”android.test.runner"/>

                                                 <application>

                                                 <instrumentation android:name="CalculatorLaunchPerformace"      //僅在源代碼下可用

                                                         android:targetPackage="com.android.calculator2"

                                                         android:label="Calculator Launch Performance">

                                                 </instrumentation>

                                                 <instrumentation

                                                         android:name="android.test.InstrumentationTestRunner"

                                                         android:targetPackage="com.android.calculator2"

                                                         android:label="Calculator Funstional Testset">

                                                  </instrumentation>

                                          </manifest>

                        (2)指定InstrumentationTestRunner文件

                                 InstrumentationTestRunner文件爲Junit測試的入口文件,在某些情況下自定義InstrumentationTestRunner類,最重要的是addTestSuite方法。他將TestCase納入TestSuite流程,調用相應的方法,過程如下:

                                         public class MusicPlayerFunctionalTestRunner extends InstrumentationTestRunner{

                                                 public TestSuite getAllTests(){

                                                         TestSuite suite=new InstrumentationTestSuite(this);

                                                         suite.addTestSuite(TestSongs.class);

                                                         suite.addTestSuite(TestPlaylist.class);

                                                         suite.addTestSuite(MusicPlayerStability.class);

                                                         retuen suite;

                                                 }

                                                 public ClassLoader getLoader(){

                                                         return MusicPlayerFunctionnalTestRunner.class.getClassLoader();

                                                 }

                                         }

                        (3)構建具體測試代碼

                                爲了測試具體的代碼,需要根據組件的類型構建相應的測試用例,其中,有兩個關鍵的方法要注意:setUp方法用來構建測試環境,如打開網絡鏈接等;tearDown方法可以確保在進入下一個測試用例前所有資源被銷燬並被回收。對於不同的測試,應該配置不同的測試類型。測試Activity的用例的實現如下:

                                        public class SpinnerTest extends ActivityInstrumentationTestCase2<RelativeLayoutStubActivity>{

                                                private Context mTargetContext;

                                                public SpinnerTest(){

                                                        super("com.android.cts.stub", RelativeLayoutStubActivity.class);

                                                }

                                                protected void setUp() throws Exception{

                                                        super.setUp();

                                                        mTargetContext=getInstrumentation().getTargetContext();

                                                }

                                                protected void tearDown() throws Exception{

                                                        super.tearDown();

                                               }

                                               public void testGetBaseline(){     //測試項方法必須以test開頭

                                                       Spinner spinner=new Spinner(mTargetContext);

                                                       assertEquals(-1, spinner,getBaseline());

                                                       spinner=(Spinner)getActivity().findViewById(R.id.spinnere1);

                                                       ArrayAdapter<CharSequence> adapter=ArrayAdapter.createFromResource(mTargetContext, com.android.cts.stub.R.array.string, android.R.layout.simple_spinner_item);

                                                      adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

                                                      spinner.setAdapter(adapter);

                                                      assertTrue(spinner.getBaseline() > 0);

                                             }

                                   }

                        (4)構建Android.mk文件

                                在源代碼中進行編譯,必須構建Android.mk文件。和普通Android.mk文件不同,Android.mk文件需要指定LOCAL_MODULE_TAGS爲tests,通過LOCAL_JAVA_LIBRARIES變量加載android.test.runner的JAR包,通過LOCAL_INSTRUMENTATION_FOR指定對那個包進行迴歸測試。下面是進行JUnit迴歸測試的Android.mk實現:

                                         LOCAL_PATH:=$(call my-dir)

                                         include $(CLEAR_VARS)

                                         LOCAL_MODULE_TAGS:=tests        //指定TAGS爲“tests”

                                         LOCAL_JAVA_LIBRARIES:=android.test.runner        //加載名爲android.test.runner的JAR包

                                         LOCAL_SRC_FILES:=$(call all -java-file-under, src)

                                         LOCAL_PACKAGE_NAMES:=CalculatorTests        //包名

                                         LOCAL_INSTRUMENTATION_FOR:=Calculator        //指定爲那個工程做迴歸測試

                                         include $(BUILD_PACKAGE)

                                利用JUnit進行迴歸測試時,如果在控制檯上發現如下錯誤提示:

                                        Application does not specify a android.test.InstrumentationTestRunner instrumentation or does not declare uses-library android.test.runner

                                應檢查AndroidManifest.xml的配置是否正確。如果Eclipse彈出提示信息“No tests found with runner 'JUnit 3',應檢查測試項目目的Run Configurations中InstrumentationTestRunner的配置是否有誤。

        (3)CTS兼容性測試

                爲了防止OEM廠商對Android的定製導致平臺的不兼容問題,Google在發佈Android版本的同時會發布相關的CTS測試。編譯CTS和啓動交互CTS控制檯的方法如下:

                        cd /path/to/android/root

                        make cts

                        cts

                執行CTS測試並設置測試參數的方法如下:

                        cts start --plan CTS -p android.os.cts.BuildVersionTest

                需要說明的是,爲了保持Android系統間的兼容性,Google規定,必須通過CTS兼容性測試,纔會授予OEM廠商Android商標和接入Android Market的權利。

                CTS兼容性測試對於不少OEM廠商甚至芯片廠商而言,是無法完全通過的。

        (4)目標環境測試

                在實際的開發過程中,如果暫時無法獲得物理設備進行測試,考慮到目標環境的差異,應該針對目標物理設備構建自定義的模擬器,這就是所謂的目標環境測試。

                1)硬件配置

                        硬件的配置可以通過AVD管理器在創建模擬器時設置,當然以後也可以變更,在默認Eclipse工作空間的登錄用戶爲root的情況下,AVD的配置位於\root\.android\avd\avdname.avd目錄下的config.ini中。下面是一個config.ini的配置:

                                hw.lcd.density=160

                                sdcard.size=200M

                                skin.name=WVGA800

                                skin.path=platforms/android-8/skins/WVGA800

                                hw.cpu.arch=arm

                                abi.type=armeabi

                                vm.heapSize=24

                                p_w_picpath.sysdir.1=platforms/android-8/p_w_picpaths

                        除了以上硬件信息外,開發者開可以配置攝像頭、電池、耳機、麥克風、GPS、LCD背光等。

                        另外\root\.android\avd\avdname.avd\hardware-qemu.ini中給出了和硬件相關的完全配置。在模擬器運行時,會檢查config.int和hardware-qemu.int中對應的配置項是否一致,當不一致時,根據config.int中的配置來修改hardware-qemu.int中的配置。

                2)網絡模式

                        在Android模擬器中,童工AVD管理器還可以模擬網絡,如是否支持GSM。通過工程的Run Configuration可以選擇網絡速度,其類型包括Full、GSM、HSCSD、GPRS、EDGE、UMTS、HSDPA等;還可以選擇網絡延遲。其類型包括None、GPRS、EDGE、UMTS等。這些在開發具有卓越用戶體驗的移動終端時非常重要。

                        網絡配置會在模擬器啓動時作爲參數傳遞給模擬器。

                3)通話/SNS/模擬

                        在DDMS中,Andoid支持通話/SMS的測試。

                        在DDMS面板中,選擇好網絡狀態,如unregistered、home、roaming、searching、denied等,做好速度和延遲配置,之後即可測試語音、數據和SMS。關於網絡狀態和無線接入協議的具體含義,涉及無線通信的協議棧內容。

                4)GPS模擬

                        Android還支持GPS模擬,可以明確指定經緯度,還可以加載GPX、GML等軌跡文件。

4.Android性能優化

        雖然目前的Android終端普遍配置了ARM Cortex A8甚至ARM Cortex A9的雙核處理器,但是這並不意味着無須優化性能。Android採取了多種手段來加快應用啓動和運行速度,還提供了多個工具供用戶分析性能的瓶頸。

        在具體的軟件開發中,智能終端雖然近今年得到了快速發展,但其所擁有的資源仍然有限,爲了減少不必要的開銷,有兩個原則必須遵守:

                不做不必要的事。

                不分配不必要的內存。

        (1)優化資源讀取

                根據資源性質的不同,Android對資源文件和SD卡資源進行了優化。

                1)資源文件

                         Android在編譯時對描述UI的XML文件進行了優化,這就是開發者將APK解包後無法打開其中的XML文件的原因。

                2)SD卡

                        對於SD卡中的數據,Android會在設備啓動和SD卡插拔時進行增量式掃描,而不是在應用加載資源時進行掃描,這無疑加快了啓動速度,事實上,這依賴於MediaScanner的實現。當然其也存在侷限性,對於文件類型沒有包含在MediaFile.java中的文件。MediaScanner就無能爲力了。

        (2)優化APK加載

                Android提供了zipalign,zipalign提供了4字節的邊界對齊來映射內存,通過空間換時間的方式來提高APK加載的執行效率。

                zipalign的用法: zipalign [-c] [-f] [-v] <align> infile.zip outfile.zip   //-c表示檢查對齊,-f表示強制覆蓋已有輸出文件

                常用的zipalign方法如下:#zipalign -v 4 infile.zip outfile.zip      //-v 代表詳細輸出。 ”4“表示4字節對齊

                對於APK的加載,如果是預製應用,Android會在系統編譯後生成後綴爲ODEX的優化文件,對於非預製應用,在第一次啓動應用時,DEX文件會被優化爲DEY文件並放置到\data\dalvik-cache目錄下,從而加快啓動速度。

        (3)Dalvik虛擬機

                在Android中,出於性能和規避知識產權方面的考慮,Google並沒有直接採用CLASS字節碼,而是先將Java代碼編譯成CLASS字節碼,然後再將CLASS字節碼轉化爲DEX字節碼。在這一過程中,Android會刪除冗餘,這很大程度上減小了APK的大小,最後將APK加載到Dalvik虛擬機中。

                在CLASS字節碼轉化爲DEX字節碼的過程中,Android對冗餘信息進行了處理。

                另外,通過Dexdump可以查看出APK文件中DEX執行情況,這有助於開發者優化自己的程序。

        (4)TraceView性能分析

                TraceView是Android提供的一個調試應用和優化性能的圖形界面工具,其包括兩個面板,Timeline Panel和Profile Panel。Timeline Panel從時間維度爲開發者提供了優化性能的視角,在Timeliness Panel的左側顯示的是不同的線程;Profile Panel從方法調用順序角度爲開發者提供了優化性能的視角。Profile Panel面板中顯示的方法有父方法和子方法,所謂父方法即調用當前方法的方法,所謂子方法即當前方法調用的方法。

                爲了通過TraceView進行性能分析,首先要在代碼中設置跟蹤的起點和終點,方法如下:
                        Debug.startMethodTracing("test");   //"test"爲生成的trace文件名

                        setContentView(R.layout.main);

                        Debug.stopMethodTracing();

                生成的trace文件會被放置在\sdcard目錄下。當然爲了在SD卡下執行寫入操作,需要如下權限:

                        <uses-permission>

                                android:name="android.permission.WRITE_EXTERNAL_STORAGE">

                        </uses-permission>

                這裏生成的trace文件爲test.trace。在將test.trace導出到Linux下後,即可通過android_sdk_linux/tools/traceview腳本進行性能分析,方法如下:

                        #cd ANDROID_SDK_HOME

                        #./tools/traceview test.trace

                Inclusive表示整個方法從調用到結束的執行時間,包含子方法執行時間;而Exclusive僅表示方法本身的執行時間。

                當然由於test.trace僅分析了setContentView的加載過程,從視圖上看不出有任何性能問題,但是在實際的開發中就不一樣了。開發者要活用TraceView,提升應用的質量。

        (5)運行效率優化

                爲了提升代碼的運行效率,必須知道最消耗計算能力的代碼段的位置,根據80/20法則,優化最重要的20%的代碼即可大幅提升代碼的運行效率。

                最直接的觀察運行效率的方法是算出代碼段在目標環境下執行時間,相應方法如下:

                        long start = System.currentTimeMillis();

                        long duration = System.currentTimeMillis()-start;        //毫秒數

                另外,通過觀察Logcat顯示的虛擬機釋放內存的情況,也可觀察出計算能力消耗的位置。

                在平臺方面,爲了充分挖掘CPU的性能,Android還針對armv5te進行了優化,充分利用armv5te的執行流水線來提高執行的效率。

                在創建新進程時,Android採用了Linux的寫時拷貝(Copy on Write)機制,是創建一個新進程非常高效。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章