Detailed explanation of the singleton pattern of android design pattern

  • 2020-05-30 21:04:03
  • OfStack

This is our most common type 1 pattern, for which there is a general feature:

Encapsulate the method and process of creation.

Encapsulation here means hiding, invisible to the object's creation methods and procedures, or a virtual process.

Hidden creation means singleton, factory method, hidden creation means builder, prototype, as for abstract factory, I think it includes the above two.

So let's think about what are the steps for creating an object?

1. What to create? -- interface definition

2. Who created it? -- decision class or help class

3. How to create? --how, creating the process

4. When is it created? -- trigger of creation time

From this, we can see that the creation type is to work on the above points

I put the singleton pattern first because it's simple and straightforward.

1. Singleton mode

gof:


Ensure a class only has one instance, and providea global point of access to it

There are 2 points:

a, only and only one instance

b provides a global access point

This means that an object can only be generated once, and can then be called globally by several methods or classes.

< Something to leave, something to be continued >

As can be seen from the above description, we usually use this mode when we only need to use one instance of the object, similar to what we often say about global objects. In j2ee, we know that the default spring initializes bean is a singleton. We can also define it in the configuration file, as follows:


<bean id="foo" class="foo" singleton="true" />

This tells the spring container that an instance of foo will only be generated once.

So where is the singleton pattern used in android?

We know that in a cell phone, if you open the input method, no matter where you open it, it's actually an instance; Activity.java has one object of mSearchManager which is also a singleton; If it is android native system, there is a global search global, if you look at the android source code, you will find that DisplayManagerGlobal, WindowManagerGlobal and many other are singletons, these objects are responsible for the management of the entire mobile phone operation processing. Let's look at the implementation of WindowManagerGlobal:


public static WindowManagerGlobal getInstance() {
        synchronized (WindowManagerGlobal.class) {
            if (sDefaultWindowManager == null) {
                sDefaultWindowManager = new WindowManagerGlobal();
            }
            return sDefaultWindowManager;
        }
    }

This system ensures that only one WindowManagerGlobal object is generated, and getInstance(global access point) is called when the system call (decision object) requires it to generate new. This is a complete implementation of the singleton pattern, a good example.

The implementation of mSearchManager is also interesting:


private void ensureSearchManager() {
        if (mSearchManager != null) {
            return;
        }

        mSearchManager = new SearchManager(this, null);
    }

Someone here is going to say, well, there's no SearchManager object returned, there's no decision class role. In fact, he does. His decision class is getSystemService, which we often use. See the code:


@Override
    public Object getSystemService(String name) {
        if (getBaseContext() == null) {
            throw new IllegalStateException(
                    "System services not available to Activities before onCreate()");
        }
        if (WINDOW_SERVICE.equals(name)) {
            return mWindowManager;
        } else if (SEARCH_SERVICE.equals(name)) {
            ensureSearchManager();
            return mSearchManager;
        }
        return super.getSystemService(name);
    }

Actually, getSystemService can be regarded as a special decision class from the following code:


if (SEARCH_SERVICE.equals(name)) {
            ensureSearchManager();
            return mSearchManager;
        }

Let's change it to:


public static SearchManager getInstance(){
     ensureSearchManager();
     return mSearchManager;
}

This is a singleton pattern. But looking at the entire getSystemService code, it is the factory method schema, which we will discuss below.

Depending on the timing of object creation, there are three ways to use the singleton pattern:

1. Hungry Chinese style -- the instance is generated when the class is loaded


public class foo{
        foo(){}
        private static foo instance =new foo();
        public static foo getlnstance(){
           return instance;
        }
}

2. Lazybones


public class foo{
        foo(){}
        private static foo instance = null ;
        public static foo getlnstance(){
            if(instance == null){
                instance = new foo();
            }
           return instance;
        }
}

3. Registration


    public static foo getInstance(String name) {
        if(name == null) {
            name = foo .class.getName();
            System.out.println("name == null"+"--->name="+name);
        }
        if(map.get(name) == null) {
            try {
                map.put(name, (foo ) Class.forName(name).newInstance());
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
        return map.get(name);
    }


The first and second approaches differ in the timing of creation, and the third in how.

Finally, ask some questions:

1. What other singletons do android have

2. Is there a singleton implementation in launcher mode

3. In the expansion of the singleton pattern, the database connection pool belongs to the variation (derivation) of which way.

4. What are the advantages and disadvantages of the three singleton modes? 1. What is the difference between common USES? .


Related articles: