編輯:關於Android編程
http頭信息帶Cache-Control域 確定緩存過期時間 防止重復請求
直接用IP直連,不用域名,策略性跟新本地IP列表。 – DNS解析過程耗時在百毫秒左右,並且還有可能存在DNS劫持。
圖片、JS、CSS等靜態資源,采用CDN(當然如果是使用7牛之類的服務就已經給你搭建布置好了)
全局圖片處理采用漏斗模型全局管控,所請求的圖片大小最好依照業務大小提供/最大不超過屏幕分辨率需要,如果請求原圖,也不要超過GL10.GL_MAX_TEXTURE_SIZE
全局縮略圖直接采用webp,在盡可能不損失圖片質量的前提下,圖片大小與png比縮小30% ~ 70%
如果列表裡的縮略圖服務器處理好的小圖,可以考慮直接在列表數據請求中,直接以base64在列表數據中直接帶上圖片(國內還比較少,海外有些這種做法,好像web端比較常見)
輪詢或者socket心跳采用系統AlarmManager提供的鬧鐘服務來做,保證在系統休眠的時候cpu可以得到休眠,在需要喚醒時可以喚醒(持有cpu喚醒鎖)
可以通過將零散的網路的請求打包進行一次操作,避免過多的無線信號引起電量消耗。
1. 傳輸數據格式選擇如果是基本需要全量數據的,考慮使用Protobuffers(序列化反序列化性能高於json)
如果傳輸回來的數據不需要全量讀取,考慮使用Flatbuffers(序列化反序列化幾乎不耗時,耗時是在讀取對象時(就這一部分如果需要優化,可以參看Flatbuffer Use Optimize2. 輸入流
使用具有緩存策略的輸入流
原
建議替換為
InputStream
BufferedInputStream
Reader
BufferedReader
II. 數據結構
如果已知大概需要多大,就直接給初始大小,減少擴容時額外開銷。
1. ListArrayList裡面就一數組,內存小,有序取值快,擴容效率低
LinkedList裡面就一雙向鏈表,內存大,隨機插入刪除快,擴容效率高。
2. HashHashSet裡面就一個HashMap,用key對外存儲,目的就是不允許重復元素。
ConcurrentHashMap線程安全,采用細分鎖,鎖顆粒更小,並發性能更優
Collections.synchronizedMap線程安全,采用當前對象作為鎖,顆粒較大,並發性能較差。
3. Int作為Key的Map
針對該特性進行了優化,采用二分法查找,簡單數組存儲。
SparseArray、SparseBooleanArray、SparseIntArray。
III. 數據庫相關
建多索引的原則: 哪個字段可以最快的減少查詢結果,就把該字段放在最前面
無法使用索引的情況操作符BETWEEN、LIKE、OR
表達式
CASE WHEN不推薦不要設計出索引是其他索引的前綴(沒有意義)
更新時拒絕直接全量更新,要更新哪列就put哪列的數據
如果最頻繁的是更新與插入,別建很多索引 (原本表就很小就也沒必要建)
拒絕用大字符串創建索引
避免建太多索引,查詢時可能就不會選擇最好的來執行推薦多使用整型索引,效率遠高於字符串索引
搜索時使用SQL參數("?", parameter)代替字符串拼接(底層有特殊優化與緩存)
查詢需要多少就limit多少(如判斷是否含有啥,就limit 1就行了嘛)
如果出現很寬的列(如blob類型),考慮放在單獨表中(在查詢或者更新其他列數據時防止不必要的大數據i/o影響性能)IV. JNI抉擇Android JVM相關知識,可參看:ART、Dalvik
Android JNI、NDK相關知識,可參看:NDK
JNI不一定顯得更快,有些會更慢。
特點: 不用在虛擬機的框子下寫代碼
可以調用更底層的高性能的代碼庫 – Good如果是Dalvik,將省去了由JIT編譯期轉為本地代碼的這個步驟。 – Good
Java調用JNI的耗時較Java調用Java肯定更慢,雖然隨著JDK版本的升級,差距已經越來越小(JDK1.6版本是5倍Java調用Java方法的耗時) – Bad
內存不在Java Heap,沒有OOM風險,有效減少gc。 – Good
一些重要的參數之類,也可以考慮放在Native層,保證安全性。參考:Android應用程序通用自動脫殼方法研究
V. 多進程抉擇
360 17個進程:360手機衛士 Android開發 InfoQ視頻 總結
充分獨立,解耦部分
大內存(如臨時展示大量圖片的Activity)、無法解決的crash、內存洩漏等問題,考慮通過獨立進程解決
獨立於UI進程,需要在後台長期存活的服務(參看Android中線程、進程與組件的關系)
非己方第三方庫(無法保證穩定、性能等問題,並且獨立組件),可考慮獨立進程
最後,多進程存在的兩個問題: 1. 由於進程間通訊或者首次調起進程的消耗等,帶來的cpu、i/o等的資源競爭。2. 也許對於部分同事來說,會還有可讀性問題吧,畢竟多了層IPC繞了點。
VI. UI層面
相關深入優化,可參看Android繪制布局相關
對於卡頓相關排查推薦參看:Android性能優化案例研究(上)與Android性能優化案例研究(下)
減少不必要的不透明背景相互覆蓋,減少重繪,因為GPU不得不一遍又一遍的畫這些圖層
保證UI線程一次完整的繪制(measure、layout、draw)不超過16ms(60Hz),否則就會出現掉幀,卡頓的現象
在UI線程中頻繁的調度中,盡量少的對象創建,減少gc等。
分步加載(減少任務顆粒)、預加載、異步加載(區別出耗時任務,采用異步加載)VII. 庫推薦
可以參考Falcon Pro作者的推薦:Falcon Pro 3如何完成獨立開發演講分析
1. 代碼編寫習慣RxJava(響應式編程,代碼更加簡潔,異步處理更快快捷、異常處理更加徹底、數據管道理念)
相關了解可以參看:RxJava
2. 圖片加載:小型快捷:Picasso(接口干淨、支持okhttp、功能強大、穩定、高效, 可以延讀:PhotoGallery、Volley、Picasso 比較)
大項目考慮:Fresco(2.5M,pipeline解決資源競爭、Native Heep解決OOM,的同時減少GC)3. 網絡底層庫:Okhttp: 默認gzip、緩存、安全等
4. 網絡基層:Retrofit: 非常好用的REST Client,結合RxJava簡單API實現、類型安全,簡單快捷
5. 數據庫層:Realm: 效率極高(Falcon Pro 3的作者Joaquim用了該庫以後,所有數據庫操作都放到了UI線程)(基於TightDB,底層C++閉源,Java層開源,簡單使用,性能遠高於SQLite等)
6. Crash上報:Fabric: 全面的信息(新版本還支持JNI Crash獲取和上報)、穩定的數據、及時的通知、強大的反混淆(其實在混淆後有上傳mapping)
7. 內存洩漏自動化檢測LeakCanary: 自動化洩漏檢測與分析 ( 可以看看這個LeakCanary使用總結與Leakcanary Square的一款Android/Java內存洩漏檢測工具)
8. 其他代碼質量:phabricator 的arc diff(盡量小顆粒度的arc diff 與update review),其實也可以看看Google是如何做的:筆記-谷歌是如何做代碼審查的,還有一點的TODO要寫好deadline與master
編包管理:Gitlab CI(結合Gitlab,功能夠用,方便)VIII. 內存洩漏相關無法解決的洩漏(如系統底層引起的)移至獨立進程(如2.x機器存在webview的內存洩漏)
大圖片資源/全屏圖片資源,要不放在assets下,要不放在nodpi下,要不都帶,否則縮放會帶來額外耗時與內存問題
4.x在AndroidManifest中配置largeHeap=true,一般dvm heep最大值可增大50%以上。
在Activity#onDestory以後,遍歷所有View,干掉所有View可能的引用(通常洩漏一個Activity,連帶洩漏其上的View,然後就洩漏了大於全屏圖片的內存)。
萬金油: 靜態化內部類,使用WeakReference引用外部類,防止內部類長期存在,洩漏了外部類的問題。圖片Decode全局統一BitmapFactory#decode出口,捕獲此處decode oom,控制長寬(小於屏幕分辨率大小 )
如果采用RGB_8888 oom了,嘗試RGB_565(相比內存小一半以上(wh2(bytes)))
如果還考慮2.x機器的話,設置BitmapFactory#options的InNativeAlloc參數為true,此時decode的內存不會上報到dvm中,便不會oom。IX. 編譯與發布考慮采用DexGuard,或ProGuard結合相關資源混淆來提高安全與包大小,參考:DexGuard、Proguard、Multi-dex
結合Gradle、Gitlab-CI 與Slack(Incoming WebHooks),快速實現,打相關git上打相關Tag,自動編相關包通知Slack。
結合Gitlab-CI與Slack(Incoming WebHooks),快速實現,所有的push,Slack快速獲知。
結合Gradle中Android提供的productFlavors參數,定義不同的variations,快速批量打渠道包X. 其他final能用就用(高效: 編譯器在調用final方法時,會轉入內嵌機制)
懶預加載,如簡單的ListView、RecyclerView等滑動列表控件,停留在當前頁面的時候,可以考慮直接預加載下個頁面所需圖片
智能預加載,通過權重等方式結合業務層面,分析出哪些更有可能被用戶浏覽使用,然後再在某個可能的時刻進行預加載。如,進入朋友圈之前通過用戶行為,智能預加載部分原圖。
做好有損體驗的准備,在一些無法避免的問題面前做好有損體驗(如,非UI進程crash,可以自己解決就不要讓用戶感知,或者UI進程crash了,做好場景恢復)
做好各項有效監控:crash(注意還有JNI的)、anr(定期掃描文件)、掉幀(繪制監控、activity生命周期監控等)、異常狀態監控(本地Log根據需要不同級別打Log並選擇性上報監控)等
文件存儲推薦放在/sdcard/Android/data/[package name]/裡(在應用卸載時,會隨即刪除)(Context#getExternalFilesDir()),而非/sdcard/根目錄建文件夾(節操問題)
通過gradle的shrinkResources與minifyEnabled參數可以簡單快速的在編包的時候自動刪除無用資源
由於resources.arsc在api8以後,aapt中默認采用UTF-8編碼,導致資源中大都是中文的resources.arsc相比采用UTF-16編碼更大,此時,可以考慮aapt中指定使用UTF-16
谷歌建議,大於10M的大型應用考慮安裝到SD卡上:App Install Location
當然運維也是一方面:Optimize Your App
在已知並且不需要棧數據的情況下,就沒有必要需要使用異常,或創建Throwable生成棧快照是一項耗時的工作。
Android Service中使用Toast無法正常顯示問題的解決方法
本文實例講述了Android Service中使用Toast無法正常顯示問題的解決方法。分享給大家供大家參考,具體如下:在做Service簡單練習時,在Service中的
Android 圖文數據JSON解析,金山詞霸每日一句API的調用
數據格式為 {sid:737, tts:http://news.iciba.com/admin/tts/2013-12-11.mp3, co
從源代碼分析Android Universal ImageLoader的緩存處理機制
通過本文帶大家一起看過UIL這個國內外大牛都追捧的圖片緩存類庫的緩存處理機制。看了UIL中的緩存實現,才發現其實這個東西不難,沒有太多的進程調度,沒有各種內存讀取控制機制
Android實現三級聯動下拉框 下拉列表spinner的實例代碼
主要實現辦法:動態加載各級下拉值的適配器在監聽本級下拉框,當本級下拉框的選中值改變時,隨之修改下級的適配器的綁定值 &