Android源码学习之单例模式应用及优点介绍

时间:2022-02-10 06:52:12

单例模式定义
ensure a class has only one instance, and provide a global point of access to it.
动态确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。
Android源码学习之单例模式应用及优点介绍

    如上图所示(截取自《head first design patterns》一书)。

Android源码学习之单例模式应用及优点介绍


通过使用private的构造函数确保了在一个应用中产生一个实例,并且是自行实例化(在singleton中自己使用new singleton())。
具体单例模式有什么优点呢
由于单例模式在内存中只有一个实例,减少了内存开销。
单例模式可以避免对资源的多重占用,例如一个写文件时,由于只有一个实例存在内存中,避免对同一个资源文件的同时写操作。
单例模式可以再系统设置全局的访问点,优化和共享资源访问。
其中使用到单例模式时,考虑较多的就是多线程的情况下如何防止被多线程同时创建等问题,其中《head first design patterns》使用到“double-checked locking”来降低使用synchronization。

复制代码 代码如下:


public class singleton {
/* the volatile keyword ensures that multiple threads
* handle the uniqueinstance variable correctly when it
* is being initialized to the singleton instance.
* */
private volatile static singleton uniqueinstance;
private singleton() {}
public static singleton getinstance() {
if(uniqueinstance == null) {
synchronized (singleton.class) {
if(uniqueinstance == null) {
uniqueinstance = new singleton();
}
}
}
return uniqueinstance;
}
}


在android源码中,使用到单例模式的例子很多,如:
一、 如inputmethodmanager类

复制代码 代码如下:


public final class inputmethodmanager {
static final boolean debug = false;
static final string tag = "inputmethodmanager";
static final object minstancesync = new object();
static inputmethodmanager minstance;
final iinputmethodmanager mservice;
final looper mmainlooper;


创建唯一的实例static inputmethodmanager minstance;

复制代码 代码如下:


/**
* retrieve the global inputmethodmanager instance, creating it if it
* doesn't already exist.
* @hide
*/
static public inputmethodmanager getinstance(context context) {
return getinstance(context.getmainlooper());
}
/**
* internally, the input method manager can't be context-dependent, so
* we have this here for the places that need it.
* @hide
*/
static public inputmethodmanager getinstance(looper mainlooper) {
synchronized (minstancesync) {
if (minstance != null) {
return minstance;
}
ibinder b = servicemanager.getservice(context.input_method_service);
iinputmethodmanager service = iinputmethodmanager.stub.asinterface(b);
minstance = new inputmethodmanager(service, mainlooper);
}
return minstance;
}


防止多线程同时创建实例

复制代码 代码如下:


synchronized (minstancesync) {
if (minstance != null) {
return minstance;
}


当没有创建实例对象时,调用minstance = new inputmethodmanager(service, mainlooper);
其中类构造函数如下所示:

复制代码 代码如下:


inputmethodmanager(iinputmethodmanager service, looper looper) {
mservice = service;
mmainlooper = looper;
mh = new h(looper);
miinputcontext = new controlledinputconnectionwrapper(looper,
mdummyinputconnection);
if (minstance == null) {
minstance = this;
}
}


二、bluetoothoppmanager类

复制代码 代码如下:


public class bluetoothoppmanager {
private static final string tag = "bluetoothoppmanager";
private static final boolean v = constants.verbose;
// 创建private static类实例
private static bluetoothoppmanager instance;
/** used when obtaining a reference to the singleton instance. */
private static object instance_lock = new object();
。。。
/**
* get singleton instance.
*/
public static bluetoothoppmanager getinstance(context context) {
synchronized (instance_lock) {
if (instance == null) {
instance = new bluetoothoppmanager();
}
instance.init(context);
return instance;
}
}


三、accessibilitymanager类

复制代码 代码如下:


public final class accessibilitymanager {
private static final boolean debug = false;
private static final string log_tag = "accessibilitymanager";
/** @hide */
public static final int state_flag_accessibility_enabled = 0x00000001;
/** @hide */
public static final int state_flag_touch_exploration_enabled = 0x00000002;
static final object sinstancesync = new object();
private static accessibilitymanager sinstance;
...
/**
* get an accessibilitymanager instance (create one if necessary).
*
* @hide
*/
public static accessibilitymanager getinstance(context context) {
synchronized (sinstancesync) {
if (sinstance == null) {
ibinder ibinder = servicemanager.getservice(context.accessibility_service);
iaccessibilitymanager service = iaccessibilitymanager.stub.asinterface(ibinder);
sinstance = new accessibilitymanager(context, service);
}
}
return sinstance;
}
/**
* create an instance.
*
* @param context a {@link context}.
* @param service an interface to the backing service.
*
* @hide
*/
public accessibilitymanager(context context, iaccessibilitymanager service) {
mhandler = new myhandler(context.getmainlooper());
mservice = service;
try {
final int stateflags = mservice.addclient(mclient);
setstate(stateflags);
} catch (remoteexception re) {
log.e(log_tag, "accessibilitymanagerservice is dead", re);
}
}


等等。。。
新年的第一周的开始,从最简单的单例模式开始记录自己的学习过程吧~~~