广

android开发

  • IOS开发
  • android开发
  • PHP编程
  • JavaScript
  • ASP.NET
  • ASP编程
  • JSP编程
  • Java编程
  • 易语言
  • Ruby编程
  • Perl编程
  • AJAX
  • 正则表达式
  • C语言
  • 编程开发

    Android源码学习之单例模式应用及优点介绍

    2018-04-04 08:35:00 次阅读 稿源:互联网
    广告
    单例模式定义
    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源码中,使用到单例模式的例子很多,如:
    一、 如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;
    }
    }

    二、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;
    }
    }

    三、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);
    }
    }

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

    一起学吧部分文章转载自互联网,供读者交流和学习,若有涉及作者版权等问题请及时与我们联系,以便更正、删除或按规定办理。感谢所有提供资讯的网站,欢迎各类媒体与一起学吧进行文章共享合作。

    广告
    广告
    广告