Android 優(yōu)化

一. 布局優(yōu)化

核心思想:減少布局文件層級(jí)
布局層級(jí)減少 -> 繪制工作量減少 ->性能提高

  1. 刪除布局中無用控件和層級(jí)
  2. 有選擇的使用ViewGroup
    • 優(yōu)先使用 LinearLayout 和 FrameLayout
    • 需要嵌套時(shí)使用 RelativeLayout(減少層級(jí))
  3. <include> 重用布局
  4. <merge> + <include> 減少層級(jí)
  5. <ViewStub> 按需加載备埃,提高初始化性能

二. 繪制優(yōu)化

核心思想:View 的 onDraw 方法避免執(zhí)行大量操作,因?yàn)?onDraw 方法可能會(huì)被頻繁調(diào)用胧弛。

  1. 避免創(chuàng)建新的局部對(duì)象:大量臨時(shí)對(duì)象占用內(nèi)存且導(dǎo)致頻繁 gc
  2. 不要做耗時(shí)任務(wù)和循環(huán):造成 View 繪制過程不流暢

三. 內(nèi)存泄漏優(yōu)化

核心思想:經(jīng)驗(yàn) + 工具

  1. 開發(fā)中避免寫出有內(nèi)存泄漏的代碼
  2. 通過分析工具找出潛在內(nèi)存泄漏并解決

避免寫出有內(nèi)存泄漏的代碼

  • Activity 被靜態(tài)變量、靜態(tài)集合猎唁、單例對(duì)象引用導(dǎo)致其無法及時(shí)銷毀

  • 屬性動(dòng)畫:

    無限循環(huán)動(dòng)畫持有 View罚舱,而View持有 Activity導(dǎo)致其無法釋放(Activity 銷毀時(shí)候調(diào)用animator.cancel()停止動(dòng)畫

  • Handler 導(dǎo)致的內(nèi)存泄漏:

    被延時(shí)處理的 Message 持有 Handler 的引用蛀醉,非靜態(tài)Handler 隱式持有對(duì) Activity 的引用,形成了message – handler – activity 這樣一條引用鏈,使得引用關(guān)系會(huì)保持至消息得到處理藤违,導(dǎo)致 Activity 的泄漏浪腐。
    解決方案:

    1. 靜態(tài)內(nèi)部類Handler + WeakReference(弱引用Activity)
    2. Activity 銷毀時(shí)候清空所有消息:handler.removeCallbacksAndMessages(null);
  • 盡量用ApplicationContext 而不是 Activity Context

  • 線程導(dǎo)致的內(nèi)存泄漏

    Thread/AsyncTask 這類線程任務(wù),若以內(nèi)部類的方式存在顿乒,隱式持有Activity议街,當(dāng)Activity銷毀時(shí)線程任務(wù)還未執(zhí)行完畢(run/doInbackground)則內(nèi)部類不會(huì)被銷毀,因此它引用的Activity也不會(huì)銷毀導(dǎo)致泄露璧榄。
    解決方案:

    1. 線程內(nèi)部類使用靜態(tài)內(nèi)部類
    2. 在線程內(nèi)部采用弱引用保存 Activity 引用
  • 及時(shí)關(guān)閉/釋放資源

    1. BraodcastReceiver 及時(shí)調(diào)用 unRegister()注銷
    2. Cursor特漩、File、Stream 及時(shí)調(diào)用 close ()關(guān)閉

工具

  • MAT
  • LeakCanary

四. 響應(yīng)速度優(yōu)化

核心思想:避免在主線程執(zhí)行耗時(shí)操作

  1. 異步執(zhí)行耗時(shí)任務(wù)
  2. ANR 日志分析:/data/anr/traces.txt

五. ListView優(yōu)化

核心思想:復(fù)用+減少耗時(shí)操作

  1. 復(fù)用 convertView:減少加載布局文件的次數(shù)(耗時(shí))
  2. 使用 ViewHolder:減少 findViewById的次數(shù)(耗時(shí))
  3. 避免在 getView 中執(zhí)行耗時(shí)操作
  4. 列表滑動(dòng)時(shí)暫停加載骨杂、空閑時(shí)執(zhí)行加載

六. Bitmap優(yōu)化

核心思想:降低圖片占用內(nèi)存大小

  1. BitmapFactory根據(jù)實(shí)際控件大小對(duì)圖片進(jìn)行采樣涂身,用到 BitmapFactory.Options 的 insimpleSize 和 inJustDecodeBounds 參數(shù)

  2. 純色盡量使用color;規(guī)則圖形盡量用shape搓蚪;稍微復(fù)雜使用9patch圖蛤售;如果不能使用9patch針對(duì)幾種主流分辨率機(jī)型進(jìn)行切圖。

七. 線程優(yōu)化

核心思想:線程池

ThreadPoolExecutor: 實(shí)現(xiàn)了 Executor 接口

執(zhí)行規(guī)則: 核心線程->任務(wù)隊(duì)列->非核心線程->拒絕執(zhí)行異常

  1. 線程池中線程數(shù)量未達(dá)到核心線程數(shù)時(shí)妒潭,會(huì)直接啟動(dòng)一個(gè)核心線程來執(zhí)行任務(wù)
  2. 若已達(dá)到或超出核心線程數(shù)量悴能,那么任務(wù)會(huì)被插入到任務(wù)隊(duì)列中排隊(duì)等待執(zhí)行
  3. 若任務(wù)隊(duì)列中無法插入(已滿),且線程數(shù)量未達(dá)到線程池規(guī)定的最大值雳灾,會(huì)立即啟動(dòng)一個(gè)非核心線程來執(zhí)行
  4. 若步驟3中線程數(shù)量已達(dá)到線程池規(guī)定的最大值會(huì)拒絕執(zhí)行此任務(wù)漠酿,會(huì)調(diào)用RejectedExecutionHandler的rejectExecution方法來通知調(diào)用者

構(gòu)造參數(shù)含義:

  • corePoolSize:核心線程數(shù),默認(rèn)核心線程會(huì)一直存活即使空閑
  • maximumPoolSize:最大線程數(shù)佑女,當(dāng)活動(dòng)線程數(shù)達(dá)到這個(gè)數(shù)值后,后續(xù)的新任務(wù)會(huì)被阻塞
  • keepAliveTime:非核心線程閑置時(shí)的超時(shí)時(shí)長谈竿,超過這個(gè)時(shí)長团驱,非核心線程就會(huì)被回收
  • unit:用于指定 keepAliveTime 參數(shù)的時(shí)間單位
  • workQueue:線程池中的任務(wù)隊(duì)列,通過線程池的 execute 方法提交的 Runnable 對(duì)象 會(huì)存儲(chǔ)在這個(gè)參數(shù)中
  • threadFactory:線程工廠空凸,為線程池提供創(chuàng)建新線程的功能嚎花。該接口只有一個(gè)方法:newThread(Runnable r)
  • RejectedExecutionHandler:當(dāng)線程池?zé)o法執(zhí)行執(zhí)行新任務(wù)時(shí)(任務(wù)隊(duì)列已滿或無法成功執(zhí)行任務(wù))這時(shí) ThreadPoolExecutor 會(huì)調(diào)用 handler 的 rejectedExecution 方法來通知調(diào)用者,默認(rèn)該方法會(huì)直接拋出一個(gè) RejectedExecutionException呀洲。

分類:

  1. SingleThreadExecutor
    只有一個(gè)核心線程紊选,可確保任務(wù)都在同一個(gè)線程中按順序執(zhí)行,不需要處理線程同步問題
  2. FixedThreadPool
    線程數(shù)量固定道逗,只有核心線程且線程空閑時(shí)不會(huì)被回收(除非線程池被關(guān)閉)兵罢,因此可更快響應(yīng)外界請(qǐng)求。
  3. CacheThreadPool
    線程數(shù)量不定滓窍,只有非核心線程(最大線程數(shù)為Integer.MAX_VALUE)卖词,空閑線程超時(shí)回收機(jī)制;適合執(zhí)行大量耗時(shí)較少的任務(wù)吏夯。
  4. ScheduledThreadPool
    核心線程數(shù)量固定此蜈,非核心線程數(shù)量無限制空閑時(shí)立即回收即横;主要用于執(zhí)行定時(shí)任務(wù)和固定周期的重復(fù)任務(wù)。

八. 一些優(yōu)化建議

  1. 避免創(chuàng)建過多的對(duì)象
  2. 整型優(yōu)先于枚舉
  3. 常量使用 static final 修飾
  4. 使用一些 Android 特有的數(shù)據(jù)結(jié)構(gòu)裆赵,如 SparseArray和Pair等
  5. 適當(dāng)使用軟引用和弱引用
  6. 采用內(nèi)存緩存和磁盤緩存
  7. 盡量采用靜態(tài)內(nèi)部類东囚,避免潛在的內(nèi)存泄漏
  8. 頻繁字符串拼接用StringBuilder
  9. 合理使用 static
    static聲明變量的生命周期和 App 的生命周期一樣的,大量的使用,會(huì)占據(jù)內(nèi)存空間不釋放战授,積少成多會(huì)造成內(nèi)存的不斷開銷页藻,直至掛掉;
    一般用來修飾基本數(shù)據(jù)類型或者輕量級(jí)對(duì)象,盡量避免修復(fù)集合或者大對(duì)象陈醒,常用作修飾全局配置項(xiàng)惕橙、工具類方法、內(nèi)部類钉跷。
Android性能優(yōu)化.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末弥鹦,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子爷辙,更是在濱河造成了極大的恐慌彬坏,老刑警劉巖,帶你破解...
    沈念sama閱讀 223,002評(píng)論 6 519
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件膝晾,死亡現(xiàn)場離奇詭異栓始,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)血当,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,357評(píng)論 3 400
  • 文/潘曉璐 我一進(jìn)店門幻赚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人臊旭,你說我怎么就攤上這事落恼。” “怎么了离熏?”我有些...
    開封第一講書人閱讀 169,787評(píng)論 0 365
  • 文/不壞的土叔 我叫張陵佳谦,是天一觀的道長。 經(jīng)常有香客問我滋戳,道長钻蔑,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,237評(píng)論 1 300
  • 正文 為了忘掉前任奸鸯,我火速辦了婚禮咪笑,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘娄涩。我一直安慰自己蒲肋,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,237評(píng)論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著兜粘,像睡著了一般申窘。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上孔轴,一...
    開封第一講書人閱讀 52,821評(píng)論 1 314
  • 那天剃法,我揣著相機(jī)與錄音,去河邊找鬼路鹰。 笑死贷洲,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的晋柱。 我是一名探鬼主播优构,決...
    沈念sama閱讀 41,236評(píng)論 3 424
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼雁竞!你這毒婦竟也來了钦椭?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,196評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤碑诉,失蹤者是張志新(化名)和其女友劉穎彪腔,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體进栽,經(jīng)...
    沈念sama閱讀 46,716評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡德挣,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,794評(píng)論 3 343
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了快毛。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片格嗅。...
    茶點(diǎn)故事閱讀 40,928評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖唠帝,靈堂內(nèi)的尸體忽然破棺而出屯掖,到底是詐尸還是另有隱情,我是刑警寧澤没隘,帶...
    沈念sama閱讀 36,583評(píng)論 5 351
  • 正文 年R本政府宣布懂扼,位于F島的核電站禁荸,受9級(jí)特大地震影響右蒲,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜赶熟,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,264評(píng)論 3 336
  • 文/蒙蒙 一瑰妄、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧映砖,春花似錦间坐、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,755評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽劳澄。三九已至,卻和暖如春蜈七,著一層夾襖步出監(jiān)牢的瞬間秒拔,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,869評(píng)論 1 274
  • 我被黑心中介騙來泰國打工飒硅, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留砂缩,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,378評(píng)論 3 379
  • 正文 我出身青樓三娩,卻偏偏與公主長得像庵芭,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子雀监,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,937評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容