代碼優(yōu)化

編寫高效代碼的兩個基本原則:
不要做冗余的工作。
盡量避免次數(shù)過多的內(nèi)存分配操作

數(shù)據(jù)結構的選擇

正確的選擇合適的數(shù)據(jù)結構很重要。
對Java中常見的數(shù)據(jù)結構--例如ArrayList和LinkedList、HashMap、HashSet等
SparseArray代替HashMap
Android原生的數(shù)據(jù)結構
SparseArray家族目前有以下四類:
SparseBooleanArray用于替代HashMap<Integer,Boolean>
SparseIntArray用于替代HashMap<Integer,Integer>
SparseLongArray用于替代HashMap<Integer,Long>
SparseArray<String>用于替代HashMap<Integer,String>
注意
SparseArray不是線程安全的
由于要進行二分查找,因此,SparseArray會對插入的數(shù)據(jù)按照Key值大小順序插入
SparseArray對刪除操作做了優(yōu)化,它并不會立即刪除這個元素,而是通過設置標識位(DELETED)的方式,后面嘗試重用。

防止內(nèi)存泄漏

Handler和內(nèi)部類的正確用法

handler消息處理機制
內(nèi)存泄漏原因
1.Handler是和Looper以及MessageQueeue一起工作。
在Android啟動后,系統(tǒng)會默認創(chuàng)建一個為主線程服務的Looper對象,該Looper對象用于處理主線程的message對象。在主線程中創(chuàng)建Handler對象時,它會立即關聯(lián)主線程Looper對象的MessageQueue這時發(fā)送到MessageQueue中的message對象都會持有Handler對象的引用,這樣在Looper處理消息時才能回調HandlerMessage方法。因此message沒有處理完成,那么Handler對象也就不會被垃圾回收。
2.Java語言中非靜態(tài)內(nèi)部類會持有外部類的一個隱式引用這樣就可能導致外部類無法回收。最終由于MessageQueue中的Message還沒有處理完成,就會持有Handler對象的引用,而非靜態(tài)的Handler對象外部類的引用,這個外部類無法被回收。
解決
1.子線程中使用Handler,這個時候開發(fā)者襲擊創(chuàng)建一個looper對象,這個Looper對象的生命周期同一般的Java對象,因此這種用法沒問題
2.將handler聲明為靜態(tài)內(nèi)部類,靜態(tài)內(nèi)部類不會持有外部類的引用,因此,不會引起內(nèi)存泄漏。

正確使用context

Context的種類
Application:Android應用中默認單例類,在activity或者service中通過getApplication()獲取到這個單例,通過context.getApplicationContext()可以獲取到應用全局唯一的Context實例。
activity/service這兩個類ContextWrapper的子類,在這兩個類中可以通過getBaseContxt()獲取到它們的Context實例,不同的activity或者service實例,它們的context都是獨立的,不會復用。、
BroadcastReceiver本身不是context的子類,但在回調函數(shù)onReceive中有android框架傳入一個context實例,它不能調用registerReceiver()以及bindService();
ContentProvider不是context子類,創(chuàng)建時系統(tǒng)會傳一個context實例,在ContentProvider中可以通過getContext()函數(shù)獲取,ContentProvider和調用者處于相同的進程中,那么getContext()返回的是應用全局唯一的context。如果其他進程調用ContentProvider,那么ContentProvider將持有自身所在進程的context實例。
錯誤使用context導致的內(nèi)存泄漏
典型的例子是單例模式使用
在應用退出之前,由于單例一直存在,會導致activity或service被引用,從而不會被垃圾回收,activity或者service中關聯(lián)的其他view或者數(shù)據(jù)結構對象也不會被釋放,從而導致內(nèi)存泄漏。
正確的是使用ApplicationContext,因為它是唯一的。

其他代碼微優(yōu)化

1-避免創(chuàng)建非必要對象
特別是在循環(huán)中重復創(chuàng)建相同對象,最好重用對象。
2-對常量使用static final
final類型的常量會進入靜態(tài)dex文件的域初始化部分,這是對基本數(shù)據(jù)類型和string類型常量的調用不會涉及類的初始化,而是直接調用字面量
3-避免內(nèi)部的Getters/Setters
Getters/Setters的作用主要是對外屏蔽具體的變量定義,從而達到更好的封裝性。
但是如果在類內(nèi)部還使用Getters/Setters函數(shù)訪問變量的話,會降低訪問的速度
4-代碼的重構

Java的四種引用方式

1-強引用
Java里對象默認的引用類型,如果一個對象具有強引用,那么垃圾回收器是不會對它進行回收操作,當內(nèi)存空間不足時,Java虛擬機將會拋出OutOfMemoryError,這是應用將會終止運行。
顯示地將引用賦值為null,JVM在合適的時間就會回收該對象
2-軟引用SoftReference
一個對象如果只有軟引用,那么當內(nèi)存空間充足時,垃圾回收器不會對它進行回收操作,只有當內(nèi)存空間不足時,這個對象才會被回收。軟引用可以用來實現(xiàn)內(nèi)存敏感的高速緩存。

MyObject aRef = new  MyObject();  
SoftReference aSoftRef=new SoftReference(aRef); 

對于這個MyObject對象,有兩個引用路徑,一個是來自SoftReference對象的軟引用,一個來自變量aReference的強引用,所以這個MyObject對象是強可及對象。
在回收這些對象之前,我們可以通過:

MyObject anotherRef=(MyObject)aSoftRef.get();  

重新獲得對該實例的強引用。而回收之后,調用get()方法就只能得到null了。
3-弱引用WeakReference
弱引用是比軟引用更弱的一種引用類型,只有弱引用指向的對象的生命周期更短,當垃圾回收器掃描到只具有弱引用時,不論當前的內(nèi)存是否不足,都會對弱引用對象進行回收。
只要JVM進行垃圾回收,被弱引用關聯(lián)的對象必定會被回收掉。不過要注意的是,這里所說的被弱引用關聯(lián)的對象是指只有弱引用與之關聯(lián),如果存在強引用同時與之關聯(lián),則進行垃圾回收時也不會回收該對象(軟引用也是如此)。

虛引用PhantomReference
虛引用并不會對所指向的對象生命周期產(chǎn)生任何影響,也就是對象還是會按照它原來的方式被垃圾回收器回收,虛引用只是一個標記作用,主要是用來跟蹤對象被垃圾回收的活動,虛引用必須和引用隊列配合使用

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • 整理一些常見的Android面試題(針對于2~3年開發(fā)經(jīng)驗中所遇到的問題) synchronized鎖靜態(tài)方法和非...
    appzy閱讀 2,448評論 4 18
  • 一.代碼優(yōu)化 1.廣播 應用程序內(nèi)部廣播通信,優(yōu)先采用LocalBroadcastManager,安全性更好,運行...
    Android_Liu閱讀 470評論 0 2
  • 前幾天整理了Java面試題集合,今天再來整理下Android相關的面試題集合.如果你希望能得到最新的消息,可以關注...
    Boyko閱讀 3,926評論 8 135
  • 看到一條魚,好玩,想學。 原文作者:Jics次元通道 效果圖 邏輯看了一遍,不是很懂,直接擼代碼 學習思路 熟悉繪...
    李汪汪汪俠閱讀 436評論 0 0
  • 11.24日:朋友圈的主題突然發(fā)現(xiàn)出現(xiàn)了很多關于感恩的話題。大家互道感謝,感謝朋友、家人和那些生活中工作中遇到的各...
    一起去追風閱讀 308評論 0 1

友情鏈接更多精彩內(nèi)容