Android source code design pattern - singleton mode analysis, system service startup registration singleton mode source code analysis

Singleton mode in Androd source code (based on android-12.0.0_r34 analysis)

Source code online reading official website: https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/app/ActivityThread.java;l=268?q=ActivityThread&ss= android%2Fplatform%2Fsuperproject

System service startup registration singleton mode source code analysis

Overview: In the Android system, we often obtain system-level services through Context and obtain them through Context's getSystemService(String name).

1.1 Obtain LayoutInflater service object (example)

Use LayoutInflater.from(Context) to obtain the LayoutInflater service and see the implementation of LayoutInflater.from(Context).

 @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    
    
        View view = LayoutInflater.from(mContext).inflate(R.layout.item_xmgl, parent, false);
        final ViewHolder holder = new ViewHolder(view);
        return holder;
    }
public static LayoutInflater from(@UiContext Context context) {
    
    
        LayoutInflater LayoutInflater =
                (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        if (LayoutInflater == null) {
    
    
            throw new AssertionError("LayoutInflater not found.");
        }
        return LayoutInflater;
    }

The from(Context) function internally calls the getSystemService(String key) method of the Context class. Looking at the Context class, this class is an abstract class.

public abstract class Context {
    
    ...}

Then the mContext we use must be a specific implementation class, we Kangkang.

View view = LayoutInflater.from(mContext).inflate(R.layout.item_xmgl, parent, false);

We usually use this code in recycleview in the list, attached to the activity.

The entry point of activity is ActivityThread.

public static void main(String[] args) {
    
    
     	......
		//主线程消息循环
        Looper.prepareMainLooper();

        ......
        //创建ActivityThread对象
        ActivityThread thread = new ActivityThread();
    	//跟进这个attach源码康康
        thread.attach(false, startSeq);
	    ......
        Looper.loop();

        throw new RuntimeException("Main thread loop unexpectedly exited");
    }

thread.attach(false, startSeq);

@@UnsupportedAppUsage
    private void attach(boolean system, long startSeq) {
    
    
        sCurrentActivityThread = this;
        mConfigurationController = new ConfigurationController(this);
        mSystemThread = system;
        if (!system) {
    
    
            android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
                                                    UserHandle.myUserId());
            RuntimeInit.setApplicationObject(mAppThread.asBinder());
            final IActivityManager mgr = ActivityManager.getService();
            try {
    
    
                //绑定mAppThread,final ApplicationThread mAppThread = new ApplicationThread();
                mgr.attachApplication(mAppThread, startSeq);
            } catch (RemoteException ex) {
    
    
                throw ex.rethrowFromSystemServer();
            }
           ......
   }

In main, create an ActivityThread object and call its attach function parameter with false. In attach, if the parameter is false (ie, non-system application), it will communicate with AtivityManagerService through the Binder mechanism, and finally call the handleLaunchActivity function.

 /**
     * @hide
     */
    @UnsupportedAppUsage
    public static IActivityManager getService() {
    
    
        return IActivityManagerSingleton.get();
    }

handleLaunchActivity

 /**
     * Extended implementation of activity launch. Used when server requests a launch or relaunch.
     */
    @Override
    public Activity handleLaunchActivity(ActivityClientRecord r,
        ......
        final Activity a = performLaunchActivity(r, customIntent);

      ......
    }

Follow up performLaunchActivity,

/**  Core implementation of activity launch. */
    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    
    
      ......
        //得到Context对象,创建Context 对象,可以看到实现类是ContextImpl
        ContextImpl appContext = createBaseContextForActivity(r);
        Activity activity = null;
        try {
    
    
            java.lang.ClassLoader cl = appContext.getClassLoader();
            //创建Activity
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
            ......
        } catch (Exception e) {
    
    
           ......
        }

  
            //创建Application 对象
            Application app = r.packageInfo.makeApplicationInner(false, mInstrumentation);
		......
            //将 appContext 等对象 attach 到 activity 中
            activity.attach(appContext, this, getInstrumentation(), r.token,
                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
                        r.embeddedID, r.lastNonConfigurationInstances, config,
                        r.referrer, r.voiceInteractor, window, r.activityConfigCallback,
                        r.assistToken, r.shareableActivityToken);
        ......
            //调用Activity的onCreate 方法
            if (r.isPersistable()) {
    
    
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
    
    
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }
        
  }

The implementation class of Context is ComtextImpl, enter Kangkang.

  // The system service cache for the system services that are cached per-ContextImpl.
  //根据ContextImpl缓存的系统服务的系统服务缓存。系统服务注册后都会放到这个缓存中。
    @UnsupportedAppUsage
    final Object[] mServiceCache = SystemServiceRegistry.createServiceCache();

Our system service creation is in SystemServiceRegistry,

/**
     * Base interface for classes that fetch services.
     * These objects must only be created during static initialization.
     */
	//获取服务的类的基本接口,这些对象只能在静态初始化期间创建。
    static abstract interface ServiceFetcher<T> {
    
    
        T getService(ContextImpl ctx);
    }

Get system services

@Override
        @SuppressWarnings("unchecked")
        public final T getService(ContextImpl ctx) {
    
    
           		
                    // Return it if we already have a cached instance.
            	    //从缓存中获取对应的系统服务
                    T service = (T) cache[mCacheIndex];
				......
                        synchronized (cache) {
    
    
                            cache[mCacheIndex] = service;
                            gates[mCacheIndex] = newState;
                            cache.notifyAll();
                  ......
                    }
                    ret = service;
                    break; // exit the for (;;)
                }
            return ret;
        }

Subclasses override this method to create service objects

public abstract T createService(ContextImpl ctx) throws ServiceNotFoundException;
 // Service registry information.
    // This information is never changed once static initialization has completed.
//Service 容器
    private static final Map<String, ServiceFetcher<?>> SYSTEM_SERVICE_FETCHERS =
            new ArrayMap<String, ServiceFetcher<?>>();

Register server

	/**
     * Statically registers a system service with the context.
     * This method must be called during static initialization only.
     */
    private static <T> void registerService(@NonNull String serviceName,
            @NonNull Class<T> serviceClass, @NonNull ServiceFetcher<T> serviceFetcher) {
    
    
        SYSTEM_SERVICE_NAMES.put(serviceClass, serviceName);
        SYSTEM_SERVICE_FETCHERS.put(serviceName, serviceFetcher);
        SYSTEM_SERVICE_CLASS_NAMES.put(serviceName, serviceClass.getSimpleName());
    }

Static statement block, executed when the class is loaded for the first time, is executed only once to ensure the uniqueness of the instance, container singleton design pattern.

static{
    
    
		registerService(Context.LAYOUT_INFLATER_SERVICE, LayoutInflater.class,
                new CachedServiceFetcher<LayoutInflater>() {
    
    
            @Override
            public LayoutInflater createService(ContextImpl ctx) {
    
    
                return new PhoneLayoutInflater(ctx.getOuterContext());
            }});	
} 

Get the corresponding service based on key

/**
     * Gets a system service from a given context.
     * @hide
     */
    public static Object getSystemService(ContextImpl ctx, String name) {
    
    
        ......
      //根据name来获取服务
        final ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name);
   ......

        final Object ret = fetcher.getService(ctx);
      ......
        return ret;
    }

1.2 Summary of system registration service source code analysis

In the ContextImpl code,
various ServiceFatchers will be registered when the class is loaded for the first time,
including the LayoutInflater Service.
Store these services in a Map in the form of key-value pairs,
obtain the corresponding ServiceFetcher based on the key,
and then obtain the specific service object through the getSystemService function of the ServiceFetcher object.
When it is retrieved for the first time,
the createService function of ServiceFetcher will be called to create a service object,
and then the object will be cached in an array.
The next time it is retrieved, it will be retrieved directly from the cache to avoid repeated creation of the object, thereby achieving the effect of a singleton.

Guess you like

Origin blog.csdn.net/weixin_46039528/article/details/132309733