Android开发中无处不在的设计模式——单例模式
2015-10-15 09:26
483 查看
对于开发人员来说,设计模式有时候就是一道坎,但是设计模式又非常有用,过了这道坎,它可以让你水平提高一个档次。而在android开发中,必要的了解一些设计模式又是非常有必要的。对于想系统的学习设计模式的同学,这里推荐2本书。一本是Head First系列的Head Hirst Design Pattern,英文好的可以看英文,可以多读几遍。另外一本是大话设计模式。
这篇文章介绍一个模式,就是单例模式,因为个人觉得这个模式理解起来最容易,而且不是太复杂。
首先了解一些什么是单例,从名字中就可以听出来就是在内存中维护唯一对象。这样做有以下几个优点
对于那些比较耗内存的类,只实例化一次可以大大提高性能,尤其是在移动开发中。
保持程序运行的时候该中始终只有一个实例存在内存中
其实单例有很多种实现方式,但是个人比较倾向于其中1种。可以见单例模式
代码如下
要保证单例,需要做一下几步
必须防止外部可以调用构造函数进行实例化,因此构造函数必须私有化。
必须定义一个静态函数获得该单例
单例使用volatile修饰
使用synchronized 进行同步处理,并且双重判断是否为null,我们看到synchronized (Singleton.class)里面又进行了是否为null的判断,这是因为一个线程进入了该代码,如果另一个线程在等待,这时候前一个线程创建了一个实例出来完毕后,另一个线程获得锁进入该同步代码,实例已经存在,没必要再次创建,因此这个判断是否是null还是必须的。
至于单例的并发测试,可以使用CountDownLatch,使用await()等待锁释放,使用countDown()释放锁从而达到并发的效果。可以见下面的代码
比如EventBus中的单例
上面的单例都是比较规规矩矩的,当然实际上有很多单例都是变了一个样子,单本质还是单例。
如InputMethodManager 中的单例
AccessibilityManager 中的单例,看代码这么长,其实就是进行了一些判断,还是一个单例
当然单例还有很多种写法,比如恶汉式,有兴趣的自己去了解就好了。
最后,我们应用一下单例模式。典型的一个应用就是管理我们的Activity,下面这个可以作为一个工具类,代码也很简单,也不做什么解释了。
这个类可以在开源中国的几个客户端中找到类似的源码
Git@OSC中的AppManager
android-app中的AppManager
以上两个类是一样的,没区别。
这篇文章介绍一个模式,就是单例模式,因为个人觉得这个模式理解起来最容易,而且不是太复杂。
首先了解一些什么是单例,从名字中就可以听出来就是在内存中维护唯一对象。这样做有以下几个优点
对于那些比较耗内存的类,只实例化一次可以大大提高性能,尤其是在移动开发中。
保持程序运行的时候该中始终只有一个实例存在内存中
其实单例有很多种实现方式,但是个人比较倾向于其中1种。可以见单例模式
代码如下
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; } }
要保证单例,需要做一下几步
必须防止外部可以调用构造函数进行实例化,因此构造函数必须私有化。
必须定义一个静态函数获得该单例
单例使用volatile修饰
使用synchronized 进行同步处理,并且双重判断是否为null,我们看到synchronized (Singleton.class)里面又进行了是否为null的判断,这是因为一个线程进入了该代码,如果另一个线程在等待,这时候前一个线程创建了一个实例出来完毕后,另一个线程获得锁进入该同步代码,实例已经存在,没必要再次创建,因此这个判断是否是null还是必须的。
至于单例的并发测试,可以使用CountDownLatch,使用await()等待锁释放,使用countDown()释放锁从而达到并发的效果。可以见下面的代码
args) { final CountDownLatch latch = new CountDownLatch(1); int threadCount = 1000; for (int i = 0; i < threadCount; i++) { new Thread() { @Override public void run() { try { latch.await(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Singleton.getInstance().hashCode()); } }.start(); } latch.countDown(); }" data-snippet-id="ext.021fffc00f359fe7464e211fe805fac2" data-snippet-saved="false" data-csrftoken="DbRdXo7B-8ijRtHpchUid61UaHNK-hG-ljkA" data-codota-status="done]public static void main(String[] args) { final CountDownLatch latch = new CountDownLatch(1); int threadCount = 1000; for (int i = 0; i < threadCount; i++) { new Thread() { @Override public void run() { try { latch.await(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Singleton.getInstance().hashCode()); } }.start(); } latch.countDown(); }
看看打印出来的hashCode会不会出现不一样即可,理论上是全部都一样的。
而在Android中,很多地方用到了单例。
比如Android-Universal-Image-Loader中的单例
[code]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()); } }
这个类可以在开源中国的几个客户端中找到类似的源码
Git@OSC中的AppManager
android-app中的AppManager
以上两个类是一样的,没区别。
相关文章推荐
- Android中Intent传递对象的两种方法(Serializable,Parcelable)
- android 5.1 如何添加一个系统service
- Android数据存储五种方式总结
- Android中SQLite数据库
- Android开发中无处不在的设计模式——单例模式
- Android Studio Gradle 缓存目录设置
- 两分钟彻底让你明白Android Activity生命周期(图文)!(转载)
- Android Api Demos登顶之路(九十八)Text-->Animation->3D Transition
- Android LayoutInflater详解
- Android ListView功能扩展,实现高性能的瀑布流布局
- android 08 AndroidManifest.xml
- android的开发基础之--------创建广播接收者的两种方式
- android开发基础之---------------自定义控件的使用
- Android:开发环境搭建相关问题
- android 07 22 23没看
- android 06 LinearLayout
- android 05 桢布局:FrameLayout 网格布据 GridLayout
- android开发自定义动态Button
- android 04 AbsoluteLayout
- android性能优化----工具篇