Android設計模式之單例模式解析
在日常開發(fā)過程中時常需要用到設計模式,但是設計模式有23種,如何將這些設計模式了然于胸并且能在實際開發(fā)過程中應用得得心應手呢?和我一起跟著《Android源碼設計模式解析與實戰(zhàn)》一書邊學邊應用吧!
今天我們要講的是單例模式
定義
確保某一個類只有一個實例,而且自行實例化并向整個系統(tǒng)提供這個實例
使用場景
確保某個類有且只有一個對象的場景,避免產生多個對象消耗過多的資源
某個類型的對象只應該有一個
使用例子
- 應用的Application
- 圖片加載框架對象,比如我們的ImageLoader,常用的圖片加載框架Glide,universal-image-loader等
- 數(shù)據請求管理類,比如可以用一個類來統(tǒng)一所有的數(shù)據請求處理,訪問數(shù)據庫,網絡請求等,這樣的類肯定只需要一個實例
實現(xiàn)
實現(xiàn)的要點
- 構造函數(shù)不對外開放,必須為Private(就是不能用New的形式生成對象)
- 通過一個靜態(tài)方法或者枚舉返回單例對象
- 確保單例類的對象有且只有一個,尤其是在多線程環(huán)境下
- 確保單例類對象在反序列化時不會重新創(chuàng)建對象
常見的實現(xiàn)方式
餓漢單例模式
public class Singleton {
private static final Singleton singleton = new Singleton();
//構造函數(shù)私有化
private Singleton() {
}
//公有的靜態(tài)函數(shù),對外暴露獲取單例對象的接口
public static Singleton getInstance() {
return singleton;
}
}
餓漢單例模式采用的是靜態(tài)變量 + fianl關鍵字的方式來確保單例模式,應用啟動的時候就生成單例對象,效率不高
懶漢模式
public class Singleton {
private static Singleton singleton;
//構造函數(shù)私有化
private Singleton() {
}
//公有的靜態(tài)函數(shù),對外暴露獲取單例對象的接口
public static synchronized Singleton getInstance() {
if (singleton == null) {
singleton = new Singleton();
}
return singleton;
}
}
懶漢模式的主要問題在于由于加了synchronized關鍵字,每調用一次getInstance方法,都會進行同步,造成了不必要的開銷
以上的2種模式用的都不多,了解一下就好,下面介紹平時用得比較多的單例模式
Double Check Lock(DCL)模式(雙重檢查鎖定模式)
public class Singleton {
private static Singleton singleton = null;
//構造函數(shù)私有化
private Singleton() {
}
//公有的靜態(tài)函數(shù),對外暴露獲取單例對象的接口
public static Singleton getInstance() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}
DCL模式是使用最多的單例模式,它不僅能保證線程安全,資源利用率高,第一次執(zhí)行getInstance時單例對象才會實例化;同時,后續(xù)調用getInstance方法時又不會有懶漢模式的重復同步的問題,效率更高;在絕大多數(shù)情況下都能保證單例對象的唯一性
DCL模式的缺點是第一次加載時由于需要同步反應會稍慢;在低于JDK1.5的版本里由于Java內存模型的原因有可能會失效
靜態(tài)內部類單例模式
public class Singleton {
private Singleton() {
}
public static Singleton getInstance() {
return SingletonHolder.sInstance;
}
//靜態(tài)內部類
private static class SingletonHolder {
private static final Singleton sInstance = new Singleton();
}
}
第一次加載Singleton類時不會初始化sInstance,只有在第一次調用getInstance方法時才會初始化sInstance,延遲了單例對象的實例化
靜態(tài)內部類單例模式不僅能保證線程安全也能保證單例對象的唯一性
靜態(tài)內部類單例模式和DCL模式是推薦的單例實現(xiàn)模式
枚舉單例
public enum Singleton {
INSTANCE;
}
默認枚舉實例的創(chuàng)建是線程安全的,并且在任何情況下它都是一個單例
其他的單例模式,在一種情況下會出現(xiàn)失效的情況——反序列化,但是枚舉即使在反序列化情況下也不會失效
總結
單例模式是運用頻率很高的模式,由于在客戶端一般沒有高并發(fā)的情況,現(xiàn)在的JDK版本也已經到了9了,一般推薦用DCL模式和靜態(tài)內部類2種實現(xiàn)。
單例對象的生命周期很長,如果持有Context,很容易引發(fā)內存泄漏,所以傳遞給單例對象的Context最好是Application Context
最后加點福利
單例模式的代碼格式都是固定的,每次都要那么寫有點麻煩,咱們可以用添加模板的方法來偷懶,詳情見圖。

添加了模板后,在需要實現(xiàn)單例模式的類里面直接輸入你的模板名字,如圖中的sin, Android Studio就會出現(xiàn)提示,回車搞定!趕緊試試吧!
源碼地址:https://github.com/snowdream1314/ImageLoader
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
Android中activity從創(chuàng)建到顯示的基本介紹
這篇文章主要給大家介紹了關于Android中activity從創(chuàng)建到顯示的相關資料,文中通過示例代碼介紹的非常詳細,對各位Android初學者們具有一定的參考學習價值,需要的朋友們下面隨著小編來一起看看吧。2017-11-11
Android EditText 監(jiān)聽用戶輸入完成的實例
下面小編就為大家分享一篇Android EditText 監(jiān)聽用戶輸入完成的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-02-02
A10_DatePicker的對話框設置(使用OnDateSetListener監(jiān)聽器)
本文主要彌補A07_TimePicker & DatePicker & AnalogClock & DigitalClock 的設置,具體實現(xiàn)代碼如下,感興趣的朋友可以參考下哈2013-06-06
Android開發(fā)重寫Animation實現(xiàn)下拉圖片后彈射回去效果示例
這篇文章主要介紹了Android開發(fā)重寫Animation實現(xiàn)下拉圖片后彈射回去效果,結合實例形式分析了Android自定義類繼承Animation實現(xiàn)圖片彈射效果的相關操作技巧,需要的朋友可以參考下2017-10-10
Android canvas drawBitmap方法詳解及實例
這篇文章主要介紹了 Android canvas drawBitmap方法詳解及實例的相關資料,需要的朋友可以參考下2017-01-01
Android通過自定義Activity實現(xiàn)懸浮的Dialog詳解
這篇文章主要給大家介紹了關于Android通過自定義Activity實現(xiàn)懸浮的Dialog的相關資料,文中給出了詳細的示例代碼供大家參考學習,對大家具有一定的參考學習價值,感興趣的朋友們下面來一起看看吧。2017-05-05
Android自定義View實現(xiàn)多邊形統(tǒng)計圖示例代碼
這篇文章主要給大家介紹了關于Android自定義View如何實現(xiàn)多邊形統(tǒng)計圖的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧。2018-01-01

