Android技术知识Android开发Android知识

每日Android源码设计模式之-一、单例模式

2017-03-09  本文已影响0人  Alexey

单例设计模式是应用最广的,它必须保证一个实例,例如一个ImageLoader实例,自行实例化并且向整个系统提供这个实例。

当创建一个对象的时候消耗过多,例如要访问IO、数据库资源等时使用。


特点

1.构造函数不对外开放,private。

2.通过一个静态方法或者枚举返回单例类对象。

3.确保单例对象只有一个,特别是多线程。

4.确保在反序列化时不会重新构建对象


分为两种:

饿汉:类一创建就new对象出来。

懒汉:使用时候才去通过判断对象是否为null来new新对象。


为了保证对象唯一,有几种实现方法:

1.懒汉DCL(DoubleCheckLock)(一般能满足需求)

双重校验同步代码块方法去new对象。

缺点:

高并发下,由于不是原子操作,可能会失效,

java5以后,可以在成员变量上加上volatile来禁止该对象上的读写指令重排序。

2.静态内部类单例模式: 推荐

3.枚举单例 避免发序列化产生对象另类:容器实现单例模式

缺点:

接口扩展困难,

如果传入的是Activity的context 很可能内存泄露

4.使用容器来实现单例。


android源码中的单例模式:

 我们常常通过context来获取系统级别的服务,如WindowsManagerService、ActivityManagerService等,跟常用的是LayoutInflater类。

下面来分析下LayoutInflater

LayoutInflater.form(context)获取单例->点进去也是调用了context.getSystemService(context.LAYOUT_INFLATER_SERVICE)

我们知道Activity对象和Context对象是在ActivityThread的main函数中生成的,找到main函数发现context是ComtextImpl.createActivityContext(this,r.pakageInfo,t.token)生成,然后通过activity.Attach传入Activity中的。

最后来看ComtextImpl类

这里使用的使用容器实现单例模式。

容器:private static final HashMap<String,ServiceFetcher> SYSTEM_SERVICE_MAP = new ...;

//在ComtextImpl类static代码块中,会生成各种ServiceFatcher,然后存入SYSTEM_SERVICE_MAP中。

ComtextImpl类有一个getSystemService(String name)方法用来获取存入SYSTEM_SERVICE_MAP中的ServiceFatcher对象,然后调用fetcher.getServiece(comtextImpl)方法。

fetcher中的getServiece方法从缓存ctxImpl.mServiceCache中获取对象cache.get(mContextCacheIndex)避免重复创建。



我们如何运用单例模式

例子:

ImageLoader使用DCL(Double checkLock)的方式来获取对象

public static InmageLoadegetInstance(){

 if(sInstance ==null){

    synchronized(ImageLoader.class){

      i f(sInstance ==null){

        sInstance = new ImageLoader();

      }

    }

  }

}

上一篇下一篇

猜你喜欢

热点阅读