1. 首先了解一些單例模式的概念
確保某一個類只有一個實例,而且自行實例化并向整個系統(tǒng)提供這個實例。
這樣做有以下幾個優(yōu)點
? 對于那些比較耗內存的類,只實例化一次可以大大提高性能,尤其是在移動開發(fā)中;
? 保持程序運行的時候該中始終只有一個實例存在內存中
有如下經典的實現(xiàn)方式:
public class Singleton {
private static volatile Singleton instance = null;
private Singleton(){
}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
以上實現(xiàn)由如下幾個十分關鍵的地方:
- ? 必須要將構造函數(shù)私有化,以防止外部可以調用構造函數(shù)進行實例化;
- ? 定義一個靜態(tài)函數(shù)獲取該實例;
- ? 定義一個全局的靜態(tài)變量,并以voliate修飾;
- ? 在實例獲取函數(shù)中,必須進行同步處理,并在同步塊中進行雙重判空;(雙重判空的原因:防止外部函數(shù)在調用該獲取實例的函數(shù)時,恰好有一個線程被阻塞等待,等此次創(chuàng)建好實例之后,那個等待的線程獲取鎖之后就不需要再創(chuàng)建該實例,因此在同步鎖內進行二次判空是有必要的)。
2. 單例模式在Android中的應用
回到Android中,是有很多地方用到了單例模式的,下面舉例說明:
1).EventBus中獲取實例:
private static volatile EventBus defaultInstance;
public static EventBus getDefault() {
if (defaultInstance == null) {
synchronized (EventBus.class) {
if (defaultInstance == null) {
defaultInstance = new EventBus();
}
}
}
return defaultInstance;
}
該單例的實現(xiàn)就是標準的精簡單例模式的實現(xiàn);
2). 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;
}
}
在輸入法服務實例的單例模式中,就是精簡的模式,即將外部判空去除了,直接進入同步塊中,當然同步塊中的判空是必不可少的;
在Android中,諸如其他的系統(tǒng)服務如:AccessibilityManager在獲取實例的時候就是采用的單例模式進行的。
3. 單例模式的自定義工具應用
應用單例模式,我們可以在創(chuàng)建自定義工具類來管理我們的Activity,代碼示例如下:
public class ActivityManager {
private static volatile ActivityManager instance;
private Stack<Activity> mActivityStack = new Stack<Activity>();
private ActivityManager(){
}
public static ActivityManager getInstance(){
if (instance == null) {
synchronized (ActivityManager.class) {
if (instance == null) {
instance = new ActivityManager();
}
}
return instance;
}
public void addActicity(Activity act){
mActivityStack.push(act);
}
public void removeActivity(Activity act){
mActivityStack.remove(act);
}
public void killMyProcess(){
int nCount = mActivityStack.size();
for (int i = nCount - 1; i >= 0; i--) {
Activity activity = mActivityStack.get(i);
activity.finish();
}
mActivityStack.clear();
android.os.Process.killProcess(android.os.Process.myPid());
}
}
這個Activity的管理工具類就是一個十分典型的應用。注意,該Activity棧是歸屬于一個實例的,因此各個方法對該數(shù)據(jù)結構進行操作時,均是針對該實例所屬的內存,因此所有的操作方法均為非靜態(tài)。
最后,安利一個十分好用的Android framework源碼查看網頁:
androidxref.com,當前已更新到 http://androidxref.com/7.1.1_r6/, 完全免費,臨時查閱很管用。
androidstudio.png