Android完美單例模式:
以前寫的單例模式考慮不完全;
面試的時候,考到這樣的問題;
想到這麼的問題,居然也會出現,只是後面才發現自己寫的單例,太過幼稚;
所以到網上找了一些資料,重新寫一個;
單例模式:
可以保證系統中一個類只有一個實例而且該實例易於外界訪問,從而方便對實例個數的控制並節約系統資源。如果希望在系統中某個類的對象只能存在一個,單例模式是最好的解決方案。
分爲:懶漢式單例、餓漢式單例、登記式單例三種;
懶漢式:用到的時候再加載;
餓漢式:一開始就加載;
登記式:使用Map等,登記對象是否實例化;有,則返回對象,無則實例化對象;
線程安全與否,在於懶漢式是否加上同步,或者是實例化時加鎖操作;
package com.example.demo;
public class HttpUtils {
//volatile的作用是: 作爲指令關鍵字,確保本條指令不會因編譯器的優化而省略,且要求每次直接讀值.
//一個定義爲volatile的變量是說這變量可能會被意想不到地改變,
//這樣,編譯器就不會去假設這個變量的值了。
//精確地說就是,優化器在用到這個變量時必須每次都小心地重新讀取這個變量的值,而不是使用保存在寄存器裏的備份。
private volatile static HttpUtils instance;
private HttpUtils()
{
//構造函數 邏輯處理
}
public static HttpUtils getInstance()
{
//第一次判斷是否爲空
if(instance==null)
{
synchronized (HttpUtils.class) {//鎖
//第二次判斷是否爲空 多線程同時走到這裏的時候,需要這樣優化處理
if(instance ==null)
{
instance =new HttpUtils();
}
}
}
return instance;
}
}
單例模式,在Android Framework 中運用廣泛;
比如說:
1、輸入法管理 InputMethodManager
2、View獲得點擊、焦點、文字改變等事件的分發管理 AccessibilityManager
public final class InputMethodManager {
static final boolean DEBUG = false;
static final String TAG = "InputMethodManager";
static final String PENDING_EVENT_COUNTER = "aq:imm";
static InputMethodManager sInstance;
InputMethodManager(IInputMethodManager service, Looper looper) {
mService = service;
mMainLooper = looper;
mH = new H(looper);
mIInputContext = new ControlledInputConnectionWrapper(looper,
mDummyInputConnection, this);
}
/**
* Retrieve the global InputMethodManager instance, creating it if it
* doesn't already exist.
* @hide
*/
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;
}
}
/**
* Private optimization: retrieve the global InputMethodManager instance,
* if it exists.
* @hide
*/
public static InputMethodManager peekInstance() {
return sInstance;
}
}