文章目录
Androd源码中的单例模式(基于android-12.0.0_r34分析)
源码在线阅读官方网址:https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/app/ActivityThread.java;l=268?q=ActivityThread&ss=android%2Fplatform%2Fsuperproject
系统服务开机注册单例模式源码解析
概述:在Android系统中我们经常会通过Context 获取系统级别的服务,通过 Context 的 getSystemService(String name)获取。
1.1 获取LayoutInflater服务对象(举例子)
使用LayoutInflater.from(Context)来获取LayoutInflater 服务,看看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;
}
from(Context)函数内部调用的是 Context 类的 getSystemService(String key)方法,到 Context 类看,该类是抽象类。
public abstract class Context {
...}
那么我们使用的mContext肯定是一个具体的实现类,我们康康.
View view = LayoutInflater.from(mContext).inflate(R.layout.item_xmgl, parent, false);
这段代码我们一般用在列表中recycleview,依附着activity。
activity的入口是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();
}
......
}
在main ,创建一个ActivityThread 对象调用了其attach 函数参数为 false。attach 中,参数为 false 的情况下(即非系统应用),会通过 Binder 机制与 AtivityManagerService 通信,并且最终调用 handleLaunchActivity 函数。
/**
* @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);
......
}
跟进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);
}
}
Context的实现类为ComtextImpl,进去康康。
// The system service cache for the system services that are cached per-ContextImpl.
//根据ContextImpl缓存的系统服务的系统服务缓存。系统服务注册后都会放到这个缓存中。
@UnsupportedAppUsage
final Object[] mServiceCache = SystemServiceRegistry.createServiceCache();
我们的系统服务创建是在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);
}
获取系统服务
@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;
}
子类覆写该方法用以创建服务对象
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<?>>();
注册服务器
/**
* 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{
registerService(Context.LAYOUT_INFLATER_SERVICE, LayoutInflater.class,
new CachedServiceFetcher<LayoutInflater>() {
@Override
public LayoutInflater createService(ContextImpl ctx) {
return new PhoneLayoutInflater(ctx.getOuterContext());
}});
}
根据 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 系统注册服务源码分析小结
ContextImpl 代码中,
第一次加载该类时会注册各种ServiceFatcher,
包含了 LayoutInflater Service。
将这些服务以键值对的形式存储在一个Map 中,
根据 key 来获取到对应的 ServiceFetcher,
然后通过 ServiceFetcher对象的 getSystemService函数来获取具体的服务对象。
当第一次获取时,
会调用 ServiceFetcher 的createService 函数创建服务对象,
然后将该对象缓存到一个数组中,
下次再取时直接从缓存中获取避免重复创建对象,从而达到单例的效果。