Android 項目優化(七):阿裡巴巴Android開發手冊整理總結

来源:https://www.cnblogs.com/renhui/archive/2019/12/04/11977754.html
-Advertisement-
Play Games

本來之前覺得Android項目優化系列的文章基本整理完畢了,但是近期看了一下《阿裡Android開發手冊》有了很多收穫,想再整理一篇,下麵就開始吧。 先在這裡列一下之前整理的文章及鏈接: Android 項目優化(一):項目代碼規範優化 Android 項目優化(二):啟動頁面優化 Android ...


本來之前覺得Android項目優化系列的文章基本整理完畢了,但是近期看了一下《阿裡Android開發手冊》有了很多收穫,想再整理一篇,下麵就開始吧。

先在這裡列一下之前整理的文章及鏈接:

Android 項目優化(一):項目代碼規範優化

Android 項目優化(二):啟動頁面優化

Android 項目優化(三):MultiDex 優化

Android 項目優化(四):記憶體優化

Android 項目優化(五):應用啟動優化

Android 項目優化(六):項目開發時優化技巧總結   下麵是《阿裡巴巴Android開發手冊》為我們提供的開發建議。

一、Android 基本組件開發規範

1. Activity 開發

必須要遵守的開發規範如下:

a). Activity 間數據通信,對於數據量比較大的,避免使用Intent + Parcelable的方式,可以考慮使用EventBus等替代方案,以免造成TransactionTooLargeException異常。

b). Activity 間通過隱式的Intent跳轉,在Intent發出去之前必須使用resolveActivity檢查,避免找不到合適的調用組件,造成ActivityNotFoundException異常。

c). Activity 動態註冊BroadCastReceiver時,registerReceiver和unregisterReceiver方法要成對出現,且生命周期對應。(否則會導致記憶體泄漏,部分華為機型對receiver進行資源管控,單個應用註冊過多receiver會觸發管控模塊拋出異常,可能會導致應用崩潰。)

建議的遵守的開發規範如下:

a). 不要在Activity的onDestroy()內執行釋放資源的工作,例如一些工作線程的銷毀和停止。因為onDestroy執行的時機可能較晚了,可以根據時機需要在Activity的onPause或onStop方法中結合isFinishing來判斷執行相應的邏輯。

b). 當前Activity的onPause方法執行結束後才會創建(onCreate)或恢復(onRestart)別的Activity,所以在onPause方法中不適合做耗時較長的操作,耗時較長的操作會影響頁面之間的跳轉效率。

c). Activity的onSaveInstanceState方法不是Activity生命周期方法,也不保證一定會被調用。它是用來在Activity被意外銷毀時保存UI狀態的,只能用於保存臨時數據,例如UI控制項的屬性,不能用於數據持久化的存儲控制。持久化存儲應該在Activity的onPause/onStop中實行。

2. Service 開發

必須要遵守的開發規範如下:

a). 避免在Service的onStartCommand/onBind方法中執行耗時操作,如果確實有需求,應改為IntentService或者採用其他非同步機制完成。

建議的遵守的開發規範如下:

a). Service需要以多線程併發處理多個啟動請求,建議使用IntentService,可避免各種複雜的配置。

b). 建議總是使用顯式的Intent啟動或者綁定Service,且不要為Service聲明Intent Filter,保證應用的安全性。如需要隱式調用,建議設置Intent的指定包名,這樣可以充分消除目標Service的不確定性。

3. BroadCastReceiver開發

必須要遵守的開發規範如下:

a). 避免在BroadCastReceiver的onReceive方法中執行耗時操作,如果有耗時工作,應該創建IntentService完成,而不應該在BroadCastReceiver內創建子線程去做。

b). 避免使用隱式的Intent廣播敏感信息,信息可能被其他註冊了對應的BroadCastReceiver的App接收。如果廣播僅限於應用內,可使用LocalBroadcastManager的sendBroadcast實現,避免敏感信息外泄和Intent攔截的風險。

建議的遵守的開發規範如下:

a). 對於只用於應用內的廣播,優先使用LocalBroadcastManager來註冊和發送,LocalBroadcastManager安全性更好,能避免敏感信息外泄和Intent攔截的風險,同時擁有更高的運行效率。

二、UI 與 佈局開發規範

必須要遵守的開發規範如下:

a). 佈局中不得不使用ViewGroup多重嵌套時,不要使用LinearLayout嵌套,改用RelativeLayout,可以降低嵌套層數。

說明:Android 應用頁面的任何一個View都需要經過measure、layout、draw三個步驟才能被正確的渲染。嵌套層級越多,帶來的measure次數越多,計算就會越費時。

b). 不要在非UI線程進行View相關的操作。

c). 不能用ScrollView包裹ListView/GridView/ExpandableListView,因為這樣會把ListView的所有Item都載入到記憶體中,需要消耗巨大的記憶體和CPU去繪製畫面。這裡推薦使用NestedScrollView。

d). 在使用Adapter的時候,如果你使用了ViewHolder做緩存,在getView()的方法中,無論這項convertView的每個子控制項是否需要設置屬性,都要顯式的設置屬性(包括文本內容、背景色及其他屬性),否則在滑動中,因為adapter item復用的原因,會出現內容的顯示錯亂。

建議的遵守的開發規範如下:

a). 在Activity中顯示對話框或彈出浮層時,儘量使用DialogFragment,而非Dialog/AlertDialog,這樣便於隨Activity生命周期管理對話框/彈出浮層的生命周期。

b). 推薦文本大小使用:dp單位。推薦View大小使用:dp單位。因為:sp是Android早期推薦使用的,但sp即受屏幕密度影響又受到系統字體設置影響,dp相對能保證UI的一致性。

c). 儘量避免在Activity沒有完全顯示時顯示PopupWindow和Dialog。

d). 儘量不要用AnimationDrawable實現幀動畫(尤其圖片多的時候),它在初始化時會將所有圖片載入到記憶體,非常消耗資源(低端機可能直接OOM),且不能釋放,釋放後下次載入會報錯。

三、進程、線程與消息通信開發規範

必須要遵守的開發規範如下:

a). 不要通過Intent在Android基礎組件之間傳遞大數據,否則可能會導致OOM。

b). 在Application的業務初始化代碼加入進程判斷,確保只在自己需要的進程初始化。特別是後臺進程減少不必要的業務初始化。

c). 新建線程時,必須通過線程池提供(AsyncTask或者ThreadPoolExecutor或者其他形式的線程池),不允許在應用中自行創建線程。

說明:使用線程池的好處是減少在創建和銷毀線程上所花的時間以及系統資源的開銷,解決資源不足的問題。如果不使用線程池,有可能造成系統創建大量同類線程而導致記憶體消耗完或者過度切換的問題。另外,創建匿名線程不便於後續的資源使用的分析,對性能分析會造成困擾。

d). 線程池不允許使用Executors去創建,而是通過ThreadPoolExecutor的方式,這樣的方式能夠讓寫的同學更加明確線程池的運行規則,規避資源耗盡的風險。

e). 子線程中不能更新界面,更新界面必須在主線程中進行,網路操作不能在主線程中調用。

建議的遵守的開發規範如下:

a). 儘量減少不同App之間的進程通信及拉起行為。拉起會導致占用系統資源,影響用戶體驗。

b). 新建線程時,定義能識別自己業務的線程名稱,便於性能優化和問題排查。

c). 使用線程池是,在業務滿足的情況下儘量設置線程的存活時間(setKeepAliveTime),確保線程空閑時能夠被釋放。

d). 儘量避免在多進程之間用SharePreferences共用數據,雖然可以通過設置MODE_MULTI_PROCESS來實現,但是這種方式官方已經不推薦使用了。

e). 謹慎使用Android的多進程,雖然多進程能降低主進程的壓力,但是需要註意以下問題:

  • 首次進入新啟動進程的頁面會有延遲現象(可能黑屏or白屏幾秒)。
  • 應用內多進程時,Application實例化多次,需要考慮各個模塊是否需要在所有進程中初始化。

四、文件與資料庫開發規範

必須要遵守的開發規範如下:

a). 任何時候都不要硬編碼文件路徑,請使用Android文件系統API訪問(硬編碼存在機型相容問題)。

b). 當使用外部存儲時,必須檢查外部存儲的可用性。

c). 應用間共用文件時,不要通過放寬文件系統的許可權去實現,而是應該使用FileProvier。

d). 資料庫Cursor必須確保使用完後關閉,以避免記憶體泄漏。

e). 多線程寫入資料庫時,需要使用事務,以免出現同步問題。

f). 執行SQL時,應該使用SQLiteDataBase的insert、update、delete方法,不要使用execSQL方法,以免SQL註入風險。

g). 如果ContentProvider管理的數據存儲在SQL資料庫中,應該避免將不受信任的外部數據直接拼接在原始SQL語句中。

建議的遵守的開發規範如下:

a). SharePreference中只能存儲簡單數據類型(int、boolean、String等),複雜數據類型建議使用文件、資料庫等其他存儲方式。

b). SharePreference提交數據時,儘量使用apply方法。除非需要確定提交結果,並據此執行後續操作時,才使用commit方法。

c). 將大數據寫入資料庫時,請使用事務或者其他能提高I/O效率的機制,保證執行速度。

五、Bitmap、Drawable與動畫

必須要遵守的開發規範如下:

a). 載入大圖或者一次性載入多張圖的時候,應該在非同步線程中進行。圖片的載入,涉及IO操作,以及CPU密集操作,很可能引起卡頓。

b). 在ListView、ViewPager、RecyclerView、GridView等組件中使用圖片時,應做好圖片的緩存,避免使用持有圖片導致記憶體溢出,也要避免重覆創建圖片,引起性能問題。推薦使用Fresco、Glide等圖片載入庫。

c). 在Activity的onPause方法或onStop方法中,關閉當前Activity正在執行的動畫。

建議的遵守的開發規範如下:

a). 推薦根據展示實際需要,壓縮圖片,而不是直接展示原圖,這樣能提高App的性能。

b). 使用完畢的圖片,應及時回收,釋放寶貴的記憶體。(2.3.3及以下版本需要調用recycle方法,2.3.3以上GC會自動管理不需要調用recycle方法)

c). 在動畫或者其他非同步任務結束時,應考慮回調時刻的環境是否還支持業務處理,並增加相關的空指針等判斷邏輯。

d). 謹慎使用Gif,註意限制每個頁面同時允許播放的gif圖片數量,以及單個gif圖片的大小。

e). 根據設備性能,選擇性的開啟複雜動畫,以實現一個整體較優的性能和體驗。

六、安全

必須要遵守的開發規範如下:

a). 將android:allowbackup屬性必須設置為false,防止應用數據被導出。

說明:android:allowbackup 是Android提供的adb調試功能,如果設置為true,可以導出應用數據併在任意設備上恢復。這會對應用安全性和用戶數據隱私構成極大的威脅,所以必須設置為false,防止數據泄漏。

b). 在SDK支持的情況下,Android必須使用v2簽名,這將對APK文件的修改做更多的保護。

c). 所有的Android基本組件(Activity、Service、BroadcastReceiver、ContentProvider等)都不應在沒有嚴格許可權控制的情況下,將android:exported設置為true。

d). 確保應用發佈的版本的android:debuggable屬性設置為true。

建議的遵守的開發規範如下:

a). 在Android 4.2以上,對安全性較高的應用可在Activity中,對Activity所關聯的Window應用WindowManager.LayoutParams.FLAG_SECURE,防止被截屏、錄屏。對於其他的Window的視窗,如Dialog、DialogFragment等,根據需要也進行相應的保護。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Linux使用MySQL Yum存儲庫上安裝MySQL 5.7,適用於Oracle Linux,Red Hat Enterprise Linux和CentOS系統。 1、添加MySQL Yum存儲庫 將MySQL Yum存儲庫添加到系統的存儲庫列表中。這是一次性操作,可以通過安裝MySQL提供的RP ...
  • 前言 Hello我又來了,快年底了,作為一個有抱負的碼農,我想給自己攢一個年終總結。自上上篇寫了手動搭建Redis集群和MySQL主從同步(非Docker)和上篇寫了動手實現MySQL讀寫分離and故障轉移之後,索性這次把資料庫中最核心的也是最難搞懂的內容,也就是索引,分享給大家。 這篇博客我會談談 ...
  • ###第一周:R基礎 rm(list = ls()) #ctr+L###矩陣相乘,函數diag()a=matrix(1:12,nrow=3,ncol=4)b=matrix(1:12,nrow=4,ncol=3)a%*%ba=matrix(1:16,nrow=4,ncol=4)diag(a)#返回對角 ...
  • ORACLE資料庫中,我們會使用一些SQL語句找出存在隱式轉換的問題SQL,其中網上流傳的一個SQL語句如下,查詢V$SQL_PLAN的欄位FILTER_PREDICATES中是否存在INTERNAL_FUNCTION: SELECT SQL_ID, PLAN_HASH_VALUEFROM V$SQ... ...
  • 在安裝neo4j之前,需要安裝Java JRE,並配置Java開發環境,然後安裝neo4j服務。 一、CentOS下安裝 1.下載Neo4j 去官網下載最新的neo4j,選擇社區版。地址:https://neo4j.com/download/other-releases/#releases 將本地下 ...
  • Frida介面功能介紹 Frida是個so級別的hook框架,它可以幫助開發、安全人員對指定的進程的so模塊進行分析。它主要提供了功能簡單的Python介面和功能豐富的JS介面,使得hook函數和修改so可以編程化,介面中包含了主控端與目標進程的交互介面。 目標進程的交互介面分為: JS介面 功能包 ...
  • 13. 高效繪圖 高效繪圖 不必要的效率考慮往往是性能問題的萬惡之源。 ——William Allan Wulf 在第12章『速度的曲率』我們學習如何用Instruments來診斷Core Animation性能問題。在構建一個iOS app的時候會遇到很多潛在的性能陷阱,但是在本章我們將著眼於有關 ...
  • Frida是什麼 我覺得官網已經說得很清楚了。簡單的說就是一款動態代碼檢測工具,可用於各種主流操作系統,這裡主要討論的是動態檢測Android系統裡面代碼運行情況。 Android版的Frida環境的搭建主要分為兩個部分,一部分是運行在Android機器上的代理工具 ,另一部分是Windows系統用 ...
一周排行
    -Advertisement-
    Play Games
  • 概述:在C#中,++i和i++都是自增運算符,其中++i先增加值再返回,而i++先返回值再增加。應用場景根據需求選擇,首碼適合先增後用,尾碼適合先用後增。詳細示例提供清晰的代碼演示這兩者的操作時機和實際應用。 在C#中,++i 和 i++ 都是自增運算符,但它們在操作上有細微的差異,主要體現在操作的 ...
  • 上次發佈了:Taurus.MVC 性能壓力測試(ap 壓測 和 linux 下wrk 壓測):.NET Core 版本,今天計劃準備壓測一下 .NET 版本,來測試並記錄一下 Taurus.MVC 框架在 .NET 版本的性能,以便後續持續優化改進。 為了方便對比,本文章的電腦環境和測試思路,儘量和... ...
  • .NET WebAPI作為一種構建RESTful服務的強大工具,為開發者提供了便捷的方式來定義、處理HTTP請求並返迴響應。在設計API介面時,正確地接收和解析客戶端發送的數據至關重要。.NET WebAPI提供了一系列特性,如[FromRoute]、[FromQuery]和[FromBody],用 ...
  • 原因:我之所以想做這個項目,是因為在之前查找關於C#/WPF相關資料時,我發現講解圖像濾鏡的資源非常稀缺。此外,我註意到許多現有的開源庫主要基於CPU進行圖像渲染。這種方式在處理大量圖像時,會導致CPU的渲染負擔過重。因此,我將在下文中介紹如何通過GPU渲染來有效實現圖像的各種濾鏡效果。 生成的效果 ...
  • 引言 上一章我們介紹了在xUnit單元測試中用xUnit.DependencyInject來使用依賴註入,上一章我們的Sample.Repository倉儲層有一個批量註入的介面沒有做單元測試,今天用這個示例來演示一下如何用Bogus創建模擬數據 ,和 EFCore 的種子數據生成 Bogus 的優 ...
  • 一、前言 在自己的項目中,涉及到實時心率曲線的繪製,項目上的曲線繪製,一般很難找到能直接用的第三方庫,而且有些還是定製化的功能,所以還是自己繪製比較方便。很多人一聽到自己畫就害怕,感覺很難,今天就分享一個完整的實時心率數據繪製心率曲線圖的例子;之前的博客也分享給DrawingVisual繪製曲線的方 ...
  • 如果你在自定義的 Main 方法中直接使用 App 類並啟動應用程式,但發現 App.xaml 中定義的資源沒有被正確載入,那麼問題可能在於如何正確配置 App.xaml 與你的 App 類的交互。 確保 App.xaml 文件中的 x:Class 屬性正確指向你的 App 類。這樣,當你創建 Ap ...
  • 一:背景 1. 講故事 上個月有個朋友在微信上找到我,說他們的軟體在客戶那邊隔幾天就要崩潰一次,一直都沒有找到原因,讓我幫忙看下怎麼回事,確實工控類的軟體環境複雜難搞,朋友手上有一個崩潰的dump,剛好丟給我來分析一下。 二:WinDbg分析 1. 程式為什麼會崩潰 windbg 有一個厲害之處在於 ...
  • 前言 .NET生態中有許多依賴註入容器。在大多數情況下,微軟提供的內置容器在易用性和性能方面都非常優秀。外加ASP.NET Core預設使用內置容器,使用很方便。 但是筆者在使用中一直有一個頭疼的問題:服務工廠無法提供請求的服務類型相關的信息。這在一般情況下並沒有影響,但是內置容器支持註冊開放泛型服 ...
  • 一、前言 在項目開發過程中,DataGrid是經常使用到的一個數據展示控制項,而通常表格的最後一列是作為操作列存在,比如會有編輯、刪除等功能按鈕。但WPF的原始DataGrid中,預設只支持固定左側列,這跟大家習慣性操作列放最後不符,今天就來介紹一種簡單的方式實現固定右側列。(這裡的實現方式參考的大佬 ...