為你的應用加速 安卓優化指南

2021-07-13 06:54:34 字數 3360 閱讀 2531

使用低端裝置 - 如果你想要你想暴露你應用的效能問題,低端裝置往往會更加的容易。效能強大的裝置往往不會太在意你應用上面的一些優化問題,且不是所有使用者都在使用這些旗艦裝置。

權衡 - 效能的優化始終圍繞著權衡這兩個字。你在某乙個點上的優化可能會造成另一點上出現問題。在很多情況下,你會花大量的時間尋找並解決這些問題,但造成這些問題的原因也可能使因為例如bitmaps的質量,或是你沒有使用正確的資料結構去儲存你的資料。所以你要時刻準備好作出一定的犧牲

inclusive cpu time - cpu在處理這個方法以及所有子方法(如被他呼叫的所有方法)的總耗時。

exclusive cpu time - cpu在處理這乙個單獨方法的總耗時。

inclusive/exlusive real time - 從方法的開始執行到執行結束的總耗時,和systrace中的「wall duration」類似

calls+recursion - 這個方法被呼叫的次數,以及被遞迴呼叫的次數。

cpu/real time per call - 在處理這個方法時的cpu耗時的平均值以及實際耗時的平均值。另外的列展示了這個方法所有呼叫的累計耗時

自動裝箱 - 自動裝箱是乙個從原始資料型別到物件型資料的裝箱過程(例如int到integer)。每當乙個原始型別資料被裝箱到乙個物件型別資料,乙個新的物件就產生了(震驚吧。。)。所以如果發生了很多次的自動裝箱,勢必會加快gc的執行頻率,而且自動裝箱是很容易被我們忽視的。而解決辦法,在使用這些型別的時候盡量一致,如果你在應用中完全使用原始資料型別,那麼盡量避免他被無緣無故的自動封裝。你可以使用我們上面提到的memery profiling工具去尋找這些過於大量的物件型別資料,也可以通過traceview去尋找類似integer.valueof(),long.valueof()這樣的方法來判斷是否發生了大量不必要的自動封裝。

hashmap vs arraymap / sparse*array - 既然提到了自動裝箱的問題,那麼使用hashmap的話,就需要我們使用物件型別作為鍵。而如果我們在整個應用中使用的都是基本資料型別的「int」,那麼在我們使用hashmap時候就會發生自動裝箱,而這時也許我們就可以考慮使用sparseintarray。而假如我們仍然需要鍵為物件型別,那麼我們可以使用arraymap。arraymap和hashmap很類似,但是在底層的實現原理卻不盡相同,這也會讓我們更加高效的使用記憶體,但要付出一定的效能代價。兩種方法都會比hashmap更加節省記憶體空間,但是相比於hashmap,查詢和增刪的速度上會有一定的犧牲。當然,除非你具有至少1000條的資料來源,否則在執行時也不會對速度造成太大的影響,這也是你使用他們替代hashmap的原因之一。

注意context - 在我們前面也看到了,activity是非常容易造成記憶體洩露的。在android中,最容易造成記憶體洩露的當屬activity。並且這些記憶體洩露會浪費大量的記憶體,因為他們持有著他們ui中所有的view,而這些view通常會佔據很多的控制項。在開發過程中的很多操作需要context,而我通常也會使用activity來傳遞。所以一定要搞清楚你對這個activity做了什麼。如果乙個引用被快取起來了,且這個物件的生命週期比你的activity還要長,那麼在我們解除這個引用之前,就會造成記憶體洩露了。

避免非靜態 - 當我們建立非靜態內部類,並且初始化它的時候,在其內部會建立乙個外部類的隱式引用。而如果內部類的生命週期比外部類還要長,那麼外部類也同樣會被保留在記憶體之中,儘管我們已經完全不需要它了。例如,在activity內建立了乙個繼承自asynctask的內部類,完後在activity執行的時候啟動這個async task,再殺掉activty。那麼這時候這個async task會保持著這個activity直到執行結束。而解決辦法也很簡單,不要這麼做,盡量使用靜態內部類。

prepare (紫色) - 在lollipop版本中,乙個新的執行緒被加入到了ui執行緒中來幫助ui的繪製。這個執行緒叫作renderthread。它負責轉換display list到opengl命令並且送至gpu。在這過程中,ui執行緒可以繼續開始處理後面的幀。而在ui執行緒將所有資源傳遞給renderthread過程中所消耗的時間,就是紫色階段所消耗的時間。如果在這過程中有很多的資源都要進行傳遞,display list會變得過多過於沉重,從而導致在這一階段過長的耗時。

process (紅色) - 執行display list中的內容並建立opengl命令。如果有過多或者過於複雜的display list需要執行的話,那麼這階段會消耗較長的時間,因為這樣的話會有很多的view被重繪。而重繪往往發生在介面的重新整理或是被移動出了被覆蓋的區域。

execute (黃色) - 傳送opengl命令到gpu。這個階段是乙個阻塞呼叫,因為cpu在這裡只會傳送乙個含有一些opengl命令的緩衝區給gpu,並且等待gpu返回空的緩衝區以便再次傳遞下一幀的opengl命令。而這些緩衝區的總量是一定的,如果gpu太過於繁忙,那麼cpu則會去等待下乙個空緩衝區。所以,如果我們看到這一階段耗時比較長,那可能是因為gpu過於繁忙的繪製ui,而造成這個的原因則可能是在短時間內繪製了過於複雜的view。

adb shell dumpsys gfxinfo

imageview - 使用setimagealpha()方法替代setalpha()。原理同上。

// using the object animator

view.setlayertype(view.layer_type_hardware, null);

objectanimator objectanimator = objectanimator.offloat(view, view.translation_x, 20f);

objectanimator.addlistener(new animatorlisteneradapter()

});objectanimator.start();

// using the property animator

view.animate().translationx(20f).withlayer().start();

如果你在呼叫了硬體view layers後改變了view,那麼會造成硬體硬體層的重新整理並且再次重頭渲染一遍view到非螢幕區域快取中。這種情況通常發生在我們使用了硬體層暫時還不支援的屬性(目前為止,硬體層只針對以下幾種屬性做了優化:otation、scale、x/y、translation、pivot和alpha)。例如,如果你另乙個view執行動畫,並且使用硬體層,在螢幕滑動他們的同時改變他的背景顏色,這就會造成硬體層的持續重新整理。而以硬體層的持續重新整理所造成的效能消耗來說,可能讓它在這裡的使用變得並不那麼值。

google io 2012上的一段演講,展示了繪製模型(drawing model)是如何工作的。

一段來自devoxx 2013的關於anrdroid效能的研討,展示了一些在anrdroid 4.4對繪製模型的一些優化,並且通過demo的形式展示了對不同優化工具的使用(systrace,overdraw等等)。

安卓禁用硬體加速 Android 優化之硬體加速

原理 可以簡單理解為通過底層軟體 將 cpu 不擅長的圖形計算轉換為 gpu 專用指令,由 gpu 完成。當目標 api 級別大於等於 14 時,硬體加速預設開啟。控制硬體加速 我們可以在以下 4 個級別控制硬體加速 在清單檔案種,加入以下屬性,為整個應用啟用硬體加速 activity 在清單檔案中...

獲取安卓應用的版本

獲取安卓應用的版本 在清單檔案androidmanifest.xml中設定程式的版本 android versionname 1.0.1 有時候我們須要在 中獲取到這個版本。1.獲取當前應用的版本號名 public string versionname try catch exception e r...

為偏執的你準備的5款安卓加密工具

你是否擔心會有人監視著你?如果是的話,安卓生態系統提供了大量緩解你這一偏執的應用。但是那款應用是必備的選擇?以下是5款你應該立即安裝並且投入使用的應用。這些應用將讓你安心,知道你的移動裝置資料遠比其他更加安全。1 orbot proxy with tor 為了在安卓上使用tor,最好的辦法是orbo...