编程语言
首页 > 编程语言> > 【Android设计模式应用】 谈谈Android中的单例模式,程序员进阶

【Android设计模式应用】 谈谈Android中的单例模式,程序员进阶

作者:互联网

//懒汉式单例类.在第一次调用的时候实例化自己
public class Singleton {
//私有的构造函数
private Singleton() {}
//私有的静态变量
private static Singleton single=null;
//暴露的公有静态方法
public static Singleton getInstance() {
if (single == null) {
single = new Singleton();
}
return single;
}
}

懒汉式(线程安全)

public class Singleton {
//私有的静态变量
private static Singleton instance;
//私有的构造方法
private Singleton (){};
//公有的同步静态方法
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}

饿汉式(线程安全)

//饿汉式单例类.在类初始化时,已经自行实例化
public class Singleton {
//static修饰的静态变量在内存中一旦创建,便永久存在
private static Singleton instance = new Singleton();
private Singleton (){}
public static Singleton getInstance() {
return instance;
}
}

static {
instance = new Singleton();
}

DCL双重校验模式

public class Singleton {
private static Singleton singleton; //静态变量
private Singleton (){} //私有构造函数
public static Singleton getInstance() {
if (singleton == null) { //第一层校验
synchronized (Singleton.class) {
if (singleton == null) { //第二层校验
singl
eton = new Singleton();
}
}
}
return singleton;
}
}

具体我们来分析一下: 假设线程A执行到了singleton = new Singleton(); 语句,这里看起来是一句代码,但是它并不是一个原子操作,这句代码最终会被编译成多条汇编指令,它大致会做三件事情:

  1. 给Singleton的实例分配内存
  2. 调用Singleton()的构造函数,初始化成员字段
  3. 将singleton对象指向分配的内存空间(即singleton不为空了)

但是在JDK1.5之后,官方给出了volatile关键字,将singleton定义的代码,为了解决DCL失效的问题。

private volatile static Singleton singleton; //使用volatile 关键字

静态内部类单例模式

public class Singleton {
private Singleton (){} ;//私有的构造函数
public static final Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
//定义的静态内部类
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton(); //创建实例的地方
}
}

枚举单例

前面的几种单例模式实现方式,一般都会稍显麻烦,或是在某些特定的情况下出现一些状况。下面介绍枚举单例模式的实现:

public enum Singleton { //enum枚举类
INSTANCE;
public void whateverMethod() {

}
}

枚举单例模式最大的优点就是写法简单,枚举在java中与普通的类是一样的,不仅能够有字段,还能够有自己的方法,最重要的是默认枚举实例是线程安全的,并且在任何情况下,它都是一个单例。即使是在反序列化的过程,枚举单例也不会重新生成新的实例。而其他几种方式,必须加入如下方法:

private Object readResolve() throws ObjectStreamException{
return INSTANCE;
}

这样的话,才能保证反序列化时不会生成新的方法

使用容器实现单例模式

public class SingletonManager {
private static Map<String, Object> objMap = new HashMap<String,Object>();//使用HashMap作为缓存容器
private Singleton() {
}
public static void registerService(String key, Objectinstance) {
if (!objMap.containsKey(key) ) {
objMap.put(key, instance) ;//第一次是存入Map
}
}
public static ObjectgetService(String key) {
return objMap.get(key) ;//返回与key相对应的对象
}
}

场景应用

  1. 那么什么时候需要考虑使用单例模式呢?
  1. 下面我们结合Android中一些源码来分析一下下

Android中常用的EventBus框架

static volatile EventBus defaultInstance;
public static EventBus getDefault() {
if (defaultInstance == null) {
synchronized (EventBus.class) {
if (defaultInstance == null) {
defaultInstance = new EventBus();
}
}
}
return defaultInstance;
}

这样的话它的资源利用率会很高,并且第一次执行的时候,是单例对象才会被实例化,但是第一次加载的时候会稍慢,可以被接受

LayouInflater的单例模式实现

LayoutInflater mInflater = LayoutInflater.from(this);

上边的写法估计没有人会陌生,获取LayoutInflater 的实例,我们一起看看具体的源码实现:

  1. 通过LayoutInflater.from(context)来获取LayoutInflater服务

/**

  1. 看看context.getSystemService是怎么工作的,context的实现类是ContextImpl类,点进去看一下

@Override
public Object getSystemService(String name) {
return SystemServiceRegistry.getSystemService(this, name);
}

  1. 进入到SystemServiceRegistry类中

/**

private static final HashMap<String, ServiceFetcher<?>> SYSTEM_SERVICE_FETCHERS =
new HashMap<String, ServiceFetcher<?>>();

/**

  1. 我们可以再看看这些服务都是在什么时候注册的

static {

registerService(Context.LAYOUT_INFLATER_SERVICE, LayoutInflater.class,
new CachedServiceFetcher() {
@Override
public LayoutInflater createService(ContextImpl ctx) {
return new PhoneLayoutInflater(ctx.getOuterContext());
}});
}

注册的

static {

registerService(Context.LAYOUT_INFLATER_SERVICE, LayoutInflater.class,
new CachedServiceFetcher() {
@Override
public LayoutInflater createService(ContextImpl ctx) {
return new PhoneLayoutInflater(ctx.getOuterContext());
}});
}

标签:Singleton,LayoutInflater,private,static,单例,Android,设计模式,public
来源: https://blog.csdn.net/m0_66264819/article/details/122760643