1.單例對象的類必須保證只有一個實例存在,而且自行實例化并向整個系統(tǒng)提供這個實例
2.使用場景:確保某個類有且只有一個對象的常見,避免產(chǎn)生多個對象消耗過多的資源或者某種類型的對象只應該有且只有一個。
3.實現(xiàn)單例模式主要有如下幾個關(guān)鍵點:
①構(gòu)造函數(shù)不對外開放,一般為private
②通過一個靜態(tài)方法或者枚舉返回單例類對象
③確保單例類的對象有且只有一個,尤其是在多線程環(huán)境下
④確保單例類對象在反序列化時不會重新構(gòu)建對象
4.Android源碼中的單例模式
一個Activity的入口是ActivityThread的main函數(shù),在main函數(shù)中創(chuàng)建一個新的ActivityThread對象,并且啟動消息循環(huán)(UI線程),創(chuàng)建新的Activity,新的Context對象,然后將該Context對象傳遞給Activity。
深入理解LayoutInflater
LayoutInflater是一個抽象類
Activity的SetContentview方法實際上調(diào)用的是Window的SetContentView而Windows是一個抽象類,上文提到的Window的具體實現(xiàn)類是PhoneWindow。
Window的View層級圖:
mDecor中會加載一個系統(tǒng)定義好的布局,這個布局中有包裹了mContentParent,而這個mContentParent就是我們設(shè)置的布局,并將添加到Parent區(qū)域在PhoneWindow的SetContentView方法中也驗證了這點。首先會構(gòu)建mContentParent這個對象,然后通過LayoutInflater的inflate函數(shù)將指定布局的視圖添加到mContentParent中
inflate方法中,主要有下面幾步:
①解析xml中的跟標簽(第一個元素)
②如果根標簽是merge,那么調(diào)用rInflate進行解析,rInflate會將merge標簽下的所有子View直接添加到根標簽中
③如果標簽是普通元素,調(diào)用createViewFromTag對該元素進行解析
④調(diào)用rInflate解析temp根元素下的所有子View并且將這些View都添加到temp下
⑤返回解析到的根視圖
單例的優(yōu)缺點
優(yōu)點:
①由于單例模式在內(nèi)存中只有一個實例,減少內(nèi)存開支,特別是一個對象需要頻繁地創(chuàng)建,銷毀。而且創(chuàng)建或銷毀時性能又無法優(yōu)化,單例模式的優(yōu)勢非常明顯。
②由于單例模式只生成一個單例,所以,減少了系統(tǒng)的性能開銷,當一個對象的產(chǎn)生需要比較多的資源時,如讀取配置,產(chǎn)生其他依賴對象時,則可以通過在應用啟動時直接產(chǎn)生一個單例對象,然后用永久駐留內(nèi)存的方式來解決
③單例模式可以避免對資源的多重占用,例如一個寫文件操作,由于只有一個實例存在內(nèi)存中,避免對同一個資源文件的同時寫操作
④單例模式可以在系統(tǒng)設(shè)置全局的訪問點,優(yōu)化和共享資源訪問,例如,可以設(shè)計一個單例類,負責所有數(shù)據(jù)表的映射處理
缺點:
①單例模式一般沒有接口,擴展很困難,若要擴展,除了修改代碼基本沒有第二種途徑可以實現(xiàn)
②單例對象如果持有Context,那么很容易引發(fā)內(nèi)存泄露,此時需要注意傳遞給單例對象的Context最好是Application Context。
####歡迎關(guān)注公共號
