zoukankan      html  css  js  c++  java
  • Android源码学习之单例模式应用

    主要内容:

    一、单例模式定义

    单例模式定义:
    Ensure a class has only one instance, and provide a global point of access to it.
    动态确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。

        

        如上图所示(截取自《Head First Design Patterns》一书)。

    通过使用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源码中的应用

      在Android源码中,使用到单例模式的例子很多,如:

    3.1 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;
            }
        }

    3.2 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;
            }
        }

    3.3 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);
            }
        }

       等等。。。

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

         

  • 相关阅读:
    如何写一个使用Web Service的IOS应用
    iPad定制相机界面
    IOS Quartz 2D 学习(1)
    cocoa Shallow Copy与Deep Copy
    sqlite3_prepare_v2返回1
    IOS 监听相机对焦事件
    UIImageView添加响应事件无响应
    二、Mongodb常用命令
    三、Mongodb Java中的使用
    多测师肖老师__第二个月python安装和pycharm安装
  • 原文地址:https://www.cnblogs.com/yemeishu/p/2843705.html
Copyright © 2011-2022 走看看