Android常见的设计模式一:单例模式
2017-03-08 17:39
281 查看
对于设计模式,我个人认为如果整篇写原理的话,应该很乏味有难懂,所以我比较喜欢白话似的解释和代码的结合。废话不多说。
必须自行创建整个实例;
必须自行向整个系统提供整个实例。
在Android中,很多地方用到了单例。
比如Android-Universal-Image-Loader中的单例
比如EventBus中的单例
上面的单例都是比较规规矩矩的,当然实际上有很多单例都是变了一个样子,单本质还是单例。
如InputMethodManager 中的单例
AccessibilityManager 中的单例,看代码这么长,其实就是进行了一些判断,还是一个单例
最后,我们应用一下单例模式。典型的一个应用就是管理我们的Activity,下面这个可以作为一个工具类,代码也很简单,也不做什么解释了。
单例模式的优缺点分析
优点:客户端使用单例模式的实例的时候,只需要调用一个单一的方法即可生成一个唯一的实例,有利于节约资源。
缺点:首先单例模式很难实现序列化,这就导致采用单例模式的类很难被持久化,当然也很难通过网络传输;其次由于单例采用静态方法,无法在继承结构中使用。
本文首先介绍常见的设计模式之一:单例模式。
单例模式是一种对象创建性模式,使用单例模式,可以保证为一个类只生成唯一的实例对象。也就是说,在整个程序空间中,该类只存在一个实例对象。
单例模式的要点有三个:
某个类只能有一个实例;必须自行创建整个实例;
必须自行向整个系统提供整个实例。
下面介绍单例模式的三个版本:
1.“饿汉式”,也就是当类加载进来的就立即实例化对象,但是这种方式比较的消耗计算机资源。
public class SingleTonFirst { // 在类被加载进入内存的时候就创建单一的Foo对象 public static final SingleTonFirst first= new SingleTonFirst (); // 构造函数私有化 private SingleTonFirst () { } // 提供一个全局的静态方法 public static SingleTonFirst getSingleTonFirst () { return first; } }
2.“懒汉式”,在单线程下能够非常好的工作,但是在多线程下存在线程安全问题。
// 这种方式在需要使用的时候才实例化 public class SingleTonTwo{ private static SingleTonTwo two; // 构造函数私有化 private SingleTonTwo () { } // 提供一个全局的静态方法 public static SingleTonTwo getSingleTonTwo () { if (two== null) { two= new SingleTonTwo (); } return two; } }
3.第三个版本:为解决多线程问题,采用了对函数进行同步的方式,但是比较浪费资源,因为每次都要进行同步检查,而实际中真正需要检查只是第一次实例化的时候.
public class SingleTonThree{ private static SingleTonThree three; // 构造函数私有化 private SingleTonThree() { } // 提供一个全局的静态方法,使用同步方法 public static synchronized SingleTonThree getSingleTonThree() { if (three== null) { three= new SingleTonThree(); } return three; } }
4.第四个版本:既解决了”懒汉式“的多线程问题,又解决了资源浪费的现象,看上去是一种不错的选择。
public class SingleTonFour{ private static SingleTonFour four; // 构造函数私有化 private SingleTonFour() { } // 提供一个全局的静态方法 public static SingleTonFourgetSingleTonFour() { if (four== null) { synchronized (SingleTonFour.class) { if (four== null) { four= new SingleTonFour(); } } } return four; } }
在Android中,很多地方用到了单例。
比如Android-Universal-Image-Loader中的单例
private volatile static ImageLoader instance; /** Returns singleton class instance */ public static ImageLoader getInstance() { if (instance == null) { synchronized (ImageLoader.class) { if (instance == null) { instance = new ImageLoader(); } } } return instance; }
比如EventBus中的单例
private static volatile EventBus defaultInstance; public static EventBus getDefault() { if (defaultInstance == null) { synchronized (EventBus.class) { if (defaultInstance == null) { defaultInstance = new EventBus(); } } } return defaultInstance; }
上面的单例都是比较规规矩矩的,当然实际上有很多单例都是变了一个样子,单本质还是单例。
如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; } }
AccessibilityManager 中的单例,看代码这么长,其实就是进行了一些判断,还是一个单例
private static AccessibilityManager sInstance; public static AccessibilityManager getInstance(Context context) { synchronized (sInstanceSync) { if (sInstance == null) { final int userId; if (Binder.getCallingUid() == Process.SYSTEM_UID || context.checkCallingOrSelfPermission( Manifest.permission.INTERACT_ACROSS_USERS) == PackageManager.PERMISSION_GRANTED || context.checkCallingOrSelfPermission( Manifest.permission.INTERACT_ACROSS_USERS_FULL) == PackageManager.PERMISSION_GRANTED) { userId = UserHandle.USER_CURRENT; } else { userId = UserHandle.myUserId(); } IBinder iBinder = ServiceManager.getService(Context.ACCESSIBILITY_SERVICE); IAccessibilityManager service = IAccessibilityManager.Stub.asInterface(iBinder); sInstance = new AccessibilityManager(context, service, userId); } } return sInstance; }
最后,我们应用一下单例模式。典型的一个应用就是管理我们的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()); } }
单例模式的优缺点分析
优点:客户端使用单例模式的实例的时候,只需要调用一个单一的方法即可生成一个唯一的实例,有利于节约资源。
缺点:首先单例模式很难实现序列化,这就导致采用单例模式的类很难被持久化,当然也很难通过网络传输;其次由于单例采用静态方法,无法在继承结构中使用。
相关文章推荐
- Android常见设计模式总结
- Android 中常见的设计模式
- android中常见的设计模式有哪些?
- android中常见的设计模式有哪些?
- Android中常见的设计模式
- [经验分享] 精通android体系架构、mvc、常见的设计模式、控制反转(ioc)
- 精通android体系架构、mvc、常见的设计模式、控制反转(ioc)
- Android中常见的设计模式
- Android开发中常见的设计模式
- Android开发中常见的设计模式(一)
- 精通android体系架构、mvc、常见的设计模式、控制反转(ioc)
- Android开发中常见的设计模式
- Android中常见的设计模式
- Android开发中常见的设计模式
- 精通android体系架构、mvc、常见的设计模式、控制反转(ioc)
- 精通android体系架构、mvc、常见的设计模式、控制反转(ioc)
- android中常见的设计模式有哪些?
- Android四种常见设计模式说明
- Android从零单排--常见设计模式
- Android开发中常见的设计模式