CameraManager 类是开放给 App 使用相机的入口类,它包括了获取相机 ID 列表、打开和关闭相机等操作,用于检测、表征和连接到 CameraDevice。
下面是 APP 获取 CameraManager 类的代码。CAMERA_SERVICE 定义在 Context 中,CAMERA_SERVICE = “camera”。
val manager = activity.getSystemService(Context.CAMERA_SERVICE) as CameraManager
由于传入的 name 既不等于 WINDOW_SERVICE,也不等于 SEARCH_SERVICE,因此会调用其父类 ContextThemeWrapper 的 getSystemService 查找。
frameworks/base/core/java/android/app/Activity.java
public class Activity extends ContextThemeWrapper
implements LayoutInflater.Factory2,
Window.Callback, KeyEvent.Callback,
OnCreateContextMenuListener, ComponentCallbacks2,
Window.OnWindowDismissedCallback {
......
@Override
public Object getSystemService(@ServiceName @NonNull 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);
}
......
}
结合以前的源码分析,不难知道最终会调用 ContextImpl 内的方法 getSystemService(…)。
frameworks/base/core/java/android/app/ContextImpl.java
class ContextImpl extends Context {
......
@Override
public Object getSystemService(String name) {
return SystemServiceRegistry.getSystemService(this, name);
}
......
}
SystemServiceRegistry 类管理所有可以由 Context#getSystemService 返回的系统服务。SYSTEM_SERVICE_FETCHERS 是一个 HashMap,其 key 类型为 String,value 是 ServiceFetcher<?>。那么这个 HashMap 在哪里填充呢?
frameworks/base/core/java/android/app/SystemServiceRegistry.java
final class SystemServiceRegistry {
......
private static final HashMap<String, ServiceFetcher<?>> SYSTEM_SERVICE_FETCHERS =
new HashMap<String, ServiceFetcher<?>>();
......
public static Object getSystemService(ContextImpl ctx, String name) {
ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name);
return fetcher != null ? fetcher.getService(ctx) : null;
}
......
}
原来是在 SystemServiceRegistry 类静态块中添加的。其中就包括了 CAMERA_SERVICE。CachedServiceFetcher 继承自 ServiceFetcher。CachedServiceFetcher 是一个抽象类,其 createService(…) 方法待实现。其 getService(…) 方法首先从 ContextImpl 成员变量 mServiceCache 获取 cache 数组,接着从对应的 mCacheIndex 拿到 Object,第一次获取由于这个“坑位”在 CachedServiceFetcher 构造函数中刚增加(mCacheIndex = sServiceCacheSize++),所以 service 必然为 null,接着就会调用 createService(…) 创建相应的对象,并给对应的缓存“坑位”赋值。
frameworks/base/core/java/android/app/SystemServiceRegistry.java
final class SystemServiceRegistry {
......
private static int sServiceCacheSize;
......
static {
......
registerService(Context.CAMERA_SERVICE, CameraManager.class,
new CachedServiceFetcher<CameraManager>() {
@Override
public CameraManager createService(ContextImpl ctx) {
return new CameraManager(ctx);
}});
......
}
......
private static <T> void registerService(String serviceName, Class<T> serviceClass,
ServiceFetcher<T> serviceFetcher) {
SYSTEM_SERVICE_NAMES.put(serviceClass, serviceName);
SYSTEM_SERVICE_FETCHERS.put(serviceName, serviceFetcher);
}
......
static abstract class CachedServiceFetcher<T> implements ServiceFetcher<T> {
private final int mCacheIndex;
public CachedServiceFetcher() {
mCacheIndex = sServiceCacheSize++;
}
@Override
@SuppressWarnings("unchecked")
public final T getService(ContextImpl ctx) {
final Object[] cache = ctx.mServiceCache 中,实际上 ;
synchronized (cache) {
// Fetch or create the service.
Object service = cache[mCacheIndex];
if (service == null) {
service = createService(ctx);
cache[mCacheIndex] = service;
}
return (T)service;
}
}
public abstract T createService(ContextImpl ctx);
}
......
}
其中 cache 数组指向 ContextImpl 类的成员变量 mServiceCache,实际上 mServiceCache 赋值再次调用了 SystemServiceRegistry 类的 createServiceCache() 方法。
frameworks/base/core/java/android/app/ContextImpl.java
class ContextImpl extends Context {
......
// The system service cache for the system services that are cached per-ContextImpl.
final Object[] mServiceCache = SystemServiceRegistry.createServiceCache();
......
}
创建用于缓存每个上下文服务实例的数组。
frameworks/base/core/java/android/app/SystemServiceRegistry.java
final class SystemServiceRegistry {
......
public static Object[] createServiceCache() {
return new Object[sServiceCacheSize];
}
......
}
现在得到了一个 CameraManager 对象。
frameworks/base/core/java/android/hardware/camera2/CameraManager.java
public final class CameraManager {
......
private final Context mContext;
private final Object mLock = new Object();
/**
* @hide
*/
public CameraManager(Context context) {
synchronized(mLock) {
mContext = context;
}
}
......
}