導航:首頁 > 操作系統 > android單例類

android單例類

發布時間:2022-11-18 01:42:18

android之單例模式:懶漢式和餓漢式的區別

比較:
餓漢式是線程安全的,在類創建的同時就已經創建好一個靜態的對象供系統使用,以後不在改變。
懶漢式如果在創建實例對象時不加上synchronized則會導致對對象的訪問不是線程安全的。

❷ android studio單例怎麼使用

android studio使用單例的情況有很多,大多數是工具類,可以使用單例,裡面有很多static方法,很方便的使用這些方法。

❸ Android中單例模式和靜態方法在效率上哪個好

很多人包括我寫單例的時候,第一想到的就是懶漢式publicclassSingleton{;privateSingleton(){}(){if(instance==null){instance=newSingleton();}returninstance;}}代碼很簡單,而且是懶載入,只有調用getInstance方法是才會初始化。但是這樣是線程不安全的,即當多個線程並行調用getInstance的時候,就會創建多個實例,不能正常工作。所以這里就有了加鎖方式,將整個getInstance方法設為同步,添加synchronized關鍵字。publicclassSingleton{;privateSingleton(){}(){if(instance==null){instance=newSingleton();}returninstance;}}這樣簡單粗暴的方式,雖然做到了線程安全,但導致了同一時間內只能有一個線程能夠調用getInstance方法。其實我們僅僅需要對初始化的代碼進行同步,這就有了雙重檢驗鎖方式。publicclassSingleton{;privateSingleton(){}(){if(instance==null){//第一次檢查synchronized(Singleton.class){if(instance==null){//第二次檢查instance=newSingleton();}}}returninstance;}}這里第二次檢查,是因為如果有多個線程同時執行完了第一次檢查,這時如果同步塊內不進行第二次檢查的話,會生成多個實例了。但是看了相關資料後,發現這樣還是有點問題。引用資料中的介紹:由於instance=newSingleton(),這並非是一個原子操作,事實上在JVM中這句話大概做了下面3件事情。1.給instance分配內存2.調用Singleton的構造函數來初始化成員變數3.將instance對象指向分配的內存空間(執行完這步instance就為非null了)但是在JVM的即時編譯器中存在指令重排序的優化。也就是說上面的第二步和第三步的順序是不能保證的,最終的執行順序可能是1-2-3也可能是1-3-2。如果是後者,則在3執行完畢、2未執行之前,被線程二搶佔了,這時instance已經是非null了(但卻沒有初始化),所以線程二會直接返回instance,然後使用,然後順理成章地報錯。我們只需要將instance變數聲明成volatile就可以了。

❹ android 幾種單例模式的寫法

先不論單例模式的寫法,有些方面是相同的,比如都需要將唯一的對象設置為static的,都需要將構造方法private化,代碼如下:
public class MyInstance { private static MyInstance instance; private MyInstance(){}
}
第一種:最原始的單例模式,代碼如下:
public static MyInstance getInstance(){ if(instance==null){ instance=new MyInstance();
} return instance;
}
多線程並發時,可能會出現重復new對象的情況,因此不提倡使用。
第二種:將整個方法塊進行加鎖,保證線程安全。
public static synchronized MyInstance getInstance(){ if(instance==null){ instance=new MyInstance();
} return instance;
}

這種代碼下,每條線程都會依次進入方法塊內部,雖然實現了單例,但是影響了運行效率,可以使用但是也不怎麼提倡。
第三種:進一步優化的方法。
public static MyInstance getsInstance(){ synchronized (MyInstance.class){ if(instance==null){ instance=new MyInstance(); return instance;
}else{ return instance;
}
}
}

這種方式只是第二種方法的一種優化,但是優化有限。
(以下的幾種方法比較推薦使用)
第四種:雙層判斷加鎖,效率影響小且保證了線程安全。
public static MyInstance getsInstance() { if (instance == null) { synchronized (MyInstance.class) { if(instance==null){ instance=new MyInstance();
}
}
} return instance;
}

這種方法是對第二種和第三種方法的進一步優化,比較推薦使用。
第五種:內部類實現單例,不用線程鎖來實現效率的提升。
public class MyInstance { private MyInstance() {
} public static MyInstance getInstance(){ return MyInstanceHolder.instance;
} private static class MyInstanceHolder{ private static MyInstance instance=new MyInstance();
}
}

在內部類中new對象,再將內部類的對象返回,這種方法是使用了java中class載入時互斥的原理來實現了線程的安全。不加線程鎖也使得運行效率不會受到較大的影響。比較提倡。

❺ android 自定義的popupwindow,可以寫成單例模式

可以啊。就像寫普通的java單例類一樣,構造方法私有,只能自己進行初始化,然後對外暴露一個初始化的靜態方法。高級點再加上線程鎖。

❻ 結合Android看看單例模式怎麼寫

單例模式常見的兩種實現方式 餓漢模式和 雙重鎖模式
•餓漢模式
public class HungrySingleton {
private static HungrySingleton mInstance = new HungrySingleton();
private HungrySingleton() {
}
public static HungrySingleton getInstance() {
return mInstance;
}
}
不得不說,餓漢模式這個名字起得的確很巧,這種方式,不管你用不用得著這個實例,先給你創建(new)出來,生怕將來創建沒機會似得,完全就是今朝有酒今朝醉的節奏。
與上面對應的還有一種就是懶漢模式,就是在用的時候才在getInstance 方法中完成實例的創建(new),真是「懶」,同時給這個方法添加synchronized 關鍵字,可以確保在多線程情況下單例依舊唯一,但是懶漢模式每次調用getInstance 方法時由於synchronized 的存在,需要進行同步,造成不必要的資源開銷。因此便有了下面雙重鎖模式的實現方式。
•雙重鎖模式(DCL 實現)
public class LazySingleton {
private static LazySingleton mInstance = null;
private LazySingleton() {
}
public static LazySingleton getInstance() {
if (mInstance == null) {
synchronized (LazySingleton.class) {
if (mInstance == null) {
mInstance = new LazySingleton();
}
}
}
return mInstance;
}
}
這樣既避免了餓漢模式的缺點,又解決了懶漢模式的不足;確保單例只在第一次真正需要的時候創建。
Android 中的使用
在日常的Android開發中,也可以見到單例模式的身影。
•Glide
使用Glide載入圖片非常方便,大家應該不陌生,可以看一下它的源碼中單例模式的實現方式。
Glide.with(this).load(url).into(imageView);
//Glide.with()
public static RequestManager with(FragmentActivity activity) {
RequestManagerRetriever retriever = RequestManagerRetriever.get();
return retriever.get(activity);
}
//RequestManagerRetriever.get()
/** The singleton instance of RequestManagerRetriever. */
private static final RequestManagerRetriever INSTANCE = new RequestManagerRetriever();
/**
* Retrieves and returns the RequestManagerRetriever singleton.
*/
public static RequestManagerRetriever get() {
return INSTANCE;
}
可以看到,當我們寫下Glide.with(..) 這行代碼時,就完成了RequestManagerRetriever 這個類的實例化,這個類的單例模式是使用餓漢模式實現的。
•EventBus
public static EventBus getDefault() {
if (defaultInstance == null) {
synchronized (EventBus.class) {
if (defaultInstance == null) {
defaultInstance = new EventBus();
}
}
}
return defaultInstance;
};
很明顯,EventBus的單例模式使用雙重鎖模式實現的。
•InputMethodManager static InputMethodManager sInstance
public static InputMethodManager getInstance() {
synchronized (InputMethodManager.class) {
if (sInstance == null) {
IBinder b = ServiceManager.getService(Context.INPUT_METHOD_SERVICE);
IInputMethodManager service = IInputMethodManager.Stub.asInterface(b);
sInstance = new InputMethodManager(service, Looper.getMainLooper());
}
return sInstance;
}
}
InputMethodManager 的單例模式是使用懶漢模式實現。
可以看到,關於單例模式的實現方式,面對不同的場景,我們可以做出不同的選擇
•Glide的單例模式雖然是使用餓漢模式實現,但理論上來說並不會造成內存資源的浪費,因為當我們通過gradle的配置引入Glide的庫時,就是為了載入圖片,必然會使用Glide.with進行相關的操作。同時RequestManagerRetriever 這個類應該是一個網路請求的管理類(Glide源碼沒有研究過,這里只是猜測),這樣的一個類必然需要使用單列模式,試想如果存在多個管理類的實例,那麼談何管理,那麼的多Request到底聽哪個manger 的,這就是前面提到必須使用單列模式的情景。

•EventBus 作為事件匯流排的更要使用單例模式了,如果說EventBus的實例不是單例模式,那麼他就無法實現它的功能了。對於EventBus不了解的同學,可以看看
EventBus 3.0 相見恨晚,EventBus真的很強大。

•InputMethodManager 使用懶漢模式實現單例也是無可厚非的,畢竟誰會去頻繁的獲取那麼多他的實例呢;同時作為一個系統的輸入法管理器,他也必須是唯一的,因此這個類也需要單例模式來實現它唯一的實例供外部使用。

由上可見,關於單例模式的實現,沒有說哪一種方式最好,只有最合適的實現方式;實際開發中,單例模式應該怎麼寫,還需要根據業務場景做最合適的選擇,無論是餓漢懶漢實用才是好漢。個人感覺,餓漢模式是一種簡單又方便的實現方式, 一個類既然已經寫成了單例模式,必然是要使用的呀,誰會去創建一個餓漢模式的單例,又不去使用這個單例呢?
之前在使用Volley的時候,就是使用餓漢模式創建整個應用的RequestQueue單例,所有需要網路請求的地方,把request添加到RequestQueue單例中即可。
public class MyApplication extends Application{
// 建立請求隊列
public static RequestQueue queue;
@Override
public void onCreate() {
super.onCreate();
queue = Volley.newRequestQueue(getApplicationContext());
}
public static RequestQueue getHttpQueue() {
return queue;
}
}
在應用Application的onCreate方法中創建了屬於整個應用的queue,之後每一次網路請求時,只需要queue.add(Request)即可,這里使用單例模式,可以有效的避免在多個地方創建RequestQueue 的實例,浪費系統資源。

❼ Android 你真的會用單例模式嗎

會用的,在app運行過程中,你只要一個實例。如播放音樂的實例,單例為了讓音樂不重疊播放!

❽ Android 開發中常用到的設計模式有哪些

2. 軟體設計模式的分類
2.1. 創建型
創建對象時,不再由我們直接實例化對象;而是根據特定場景,由程序來確定創建對象的方式,從而保證更大的性能、更好的架構優勢。創建型模式主要有簡單工廠模式(並不是23種設計模式之一)、工廠方法、抽象工廠模式、單例模式、生成器模式和原型模式。
2.2. 結構型
用於幫助將多個對象組織成更大的結構。結構型模式主要有適配器模式adapter、橋接模式bridge、組合器模式component、裝飾器模式decorator、門面模式、亨元模式flyweight和代理模式proxy。
2.3. 行為型
用於幫助系統間各對象的通信,以及如何控制復雜系統中流程。行為型模式主要有命令模式command、解釋器模式、迭代器模式、中介者模式、備忘錄模式、觀察者模式、狀態模式state、策略模式、模板模式和訪問者模式。
3. 常見設計模式介紹
3.1. 單例模式(singleton)
有些時候,允許自由創建某個類的實例沒有意義,還可能造成系統性能下降。如果一個類始終只能創建一個實例,則這個類被稱為單例類,這種模式就被稱為單例模式。
一般建議單例模式的方法命名為:getInstance(),這個方法的返回類型肯定是單例類的類型了。getInstance方法可以有參數,這些參數可能是創建類實例所需要的參數,當然,大多數情況下是不需要的

❾ android中什麼是單例模式

單例模式(Singleton)
一、 什麼是單例模式
單例模式,簡單點來說就是設計一個類,使其在任何時候,最多隻有一個實例,並提供一個訪問這個實例的全局訪問點。

二、 為什麼要單例
在程序中的很多地方,只有一個實例是非常重要的。例如,在windows中,任務管理器只有一個,無論你點擊多少次打開任務管理器,任務管理器也只會生成一個窗口。再例如,在一些軟體中,工具箱是唯一的,無論你點擊多少次打開工具箱,工具箱也只一個。

為什麼要這樣設計呢?因為像任務管理器或工具箱這樣的程序,只要有一個就足夠完成所有的工作了,多個程序只會白白消耗系統資源,而像任務管理器這類的程序還會引入多個任務管理器之間的同步問題,所以對些這些程序來說,只有一個實例或程序是必要的。

三、 為什麼需要單例模式
上面講到對於某些程序來說,保持其只有一個實例是必要的,但是如何保證一個程序或一個類只有一個實例呢?下面從類的角度來解說。

❿ 如何使用android單例模式

java模式之單例模式:
單例模式確保一個類只有一個實例,自行提供這個實例並向整個系統提供這個實例。
特點:
1,一個類只能有一個實例
2,自己創建這個實例
3,整個系統都要使用這個實例

Singleton模式主要作用是保證在Java應用程序中,一個類Class只有一個實例存在。在很多操作中,比如建立目錄
資料庫連接都需要這樣的單線程操作。一些資源管理器常常設計成單例模式。
外部資源:譬如每台計算機可以有若干個列印機,但只能有一個Printer
Spooler,以避免兩個列印作業同時輸出到列印機中。每台計算機可以有若干個通信埠,系統應當集中管理這些通信埠,以避免一個通信埠被兩個請求同時調用。內部資源,譬如,大多數的軟體都有一個(甚至多個)屬性文件存放系統配置。這樣的系統應當由一個對象來管理這些屬性文件。

一個例子:Windows
回收站。
在整個視窗系統中,回收站只能有一個實例,整個系統都使用這個惟一的實例,而且回收站自行提供自己的實例。因此,回收站是單例模式的應用。

兩種形式:
1,餓漢式單例類

public class Singleton {

private Singleton(){}

//在自己內部定義自己一個實例,是不是很奇怪?

//注意這是private 只供內部調用

private static Singleton instance =
new Singleton();

//這里提供了一個供外部訪問本class的靜態方法,可以直接訪問

public static Singleton getInstance() {

return instance;

}

}

2,懶漢式單例類

public class Singleton {

private static Singleton instance = null;

public static synchronized Singleton
getInstance() {

//這個方法比上面有所改進,不用每次都進行生成對象,只是第一次

//使用時生成實例,提高了效率!

if (instance==null)

instance=new Singleton();

return instance; }

}

第二中形式是lazy initialization,也就是說第一次調用時初始Singleton,以後就不用再生成了。

注意到lazy
initialization形式中的synchronized,這個synchronized很重要,如果沒有synchronized,那麼使用getInstance()是有可能得到多個Singleton實例。
一般來說第一種比較安全

我自己比較常用的方式:

public class Singleton {

private volatile static
Singleton singleton;

private Singleton(){}

public static Singleton getInstance(){

if(singleton==null){

synchronized(Singleton.class){

if(singleton==null){

singleton=new Singleton();

}

}

}

return singleton;

}

}

閱讀全文

與android單例類相關的資料

熱點內容
dvd光碟存儲漢子演算法 瀏覽:757
蘋果郵件無法連接伺服器地址 瀏覽:963
phpffmpeg轉碼 瀏覽:671
長沙好玩的解壓項目 瀏覽:145
專屬學情分析報告是什麼app 瀏覽:564
php工程部署 瀏覽:833
android全屏透明 瀏覽:737
阿里雲伺服器已開通怎麼辦 瀏覽:803
光遇為什麼登錄時伺服器已滿 瀏覽:302
PDF分析 瀏覽:485
h3c光纖全工半全工設置命令 瀏覽:143
公司法pdf下載 瀏覽:382
linuxmarkdown 瀏覽:350
華為手機怎麼多選文件夾 瀏覽:683
如何取消命令方塊指令 瀏覽:349
風翼app為什麼進不去了 瀏覽:778
im4java壓縮圖片 瀏覽:362
數據查詢網站源碼 瀏覽:150
伊克塞爾文檔怎麼進行加密 瀏覽:892
app轉賬是什麼 瀏覽:163