前言
在Android
系统中,我们经常会通过Context
获取系统级别的服务,如WindowManagerService
、ActivityManagerService
等,更长用的是一个LayoutInflater
的类,这些服务会在合适的时候以单例的形式注册在系统中,在我们需要的时候就通过Context
的getSystemService(String name)
获取。我们以常用的LayoutInflater
为例来说明。
ListView的getView方法
平时我们使用LayoutInflater
较为常见的地方是在ListView
适配器的getView()
中。代码
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = LayoutInflater.from(parent.getContext()).inflate(mLayoutId, parent, false);
convertView.setTag(holder);
}else{
convertView = (ViewHolder)paramView.getTag();
}
return convertView;
}
通常我们使用LayoutInflater.from(Context)
来获取LayoutInflater
服务,下面看看LayoutInflater.from(Context)
的实现。
public static LayoutInflater from(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{
}
其实在Application
、Activity
、Service
中都会存在一个Context对象,即Context
的总数为Activity
个数+Service
个数+1
。而ListView
通常显示在Activity
中,那我们就以Activity
中的Context
分析。
ActivityThread的main方法
我们知道,一个Activity
的入口是ActivityThread
的main
函数,在main
函数中创建一个新的ActivityThread
对象,并且启动消息循环,创建新的Activity
、新的Context
对象,然后将该Context
对象传递给Activity
。下面看下ActivityThread
的源码
public static void main(String[] args) {
...
//主线程消息循环
Looper.prepareMainLooper();
//创建ActivityThread对象
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
...
Looper.loop();
}
private void attach(boolean system) {
sCurrentActivityThread = this;
mSystemThread = system;
//不是系统应用
if (!system) {
ViewRootImpl.addFirstDrawHandler(new Runnable() {
@Override
public void run() {
ensureJitEnabled();
}
});
android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
UserHandle.myUserId());
RuntimeInit.setApplicationObject(mAppThread.asBinder());
final IActivityManager mgr = ActivityManagerNative.getDefault();
try {
//关联appThread
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
...
} else {
...
try {
mInstrumentation = new Instrumentation();
//创建application的Context
ContextImpl context = ContextImpl.createAppContext(
this, getSystemContext().mPackageInfo);
mInitialApplication = context.mPackageInfo.makeApplication(true, null);
mInitialApplication.onCreate();
} catch (Exception e) {
throw new RuntimeException(
"Unable to instantiate Application():" + e.toString(), e);
}
}
}
在main
方法中创建一个ActivityThread
对象后,调用了其attch()
方法,在attch()
方法中,参数为false
的情况下(即非系统应用),会通过Binder
机制与ActivityManagerService
通讯,并且最终调用handleLaunchActivity()
方法,看下具体实现:
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
...
Activity a = performLaunchActivity(r, customIntent);
...
//Activity的OnResume生命周期
handleResumeActivity();
}
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
...
Activity activity = null;
try {
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
//创建Activity
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
StrictMode.incrementExpectedActivityCount(activity.getClass());
r.intent.setExtrasClassLoader(cl);
r.intent.prepareToEnterProcess();
if (r.state != null) {
r.state.setClassLoader(cl);
}
}
...
try {
//创建Application对象
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
if (activity != null) {
//创建Context
Context appContext = createBaseContextForActivity(r, activity);
CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
Configuration config = new Configuration(mCompatConfiguration);
//将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);
...
activity.mCalled = false;
if (r.isPersistable()) {
//Activity的OnCreate生命周期
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
...
//Activity的onStart生命周期
activity.performStart();
...
}
...
}
return activity;
}
private Context createBaseContextForActivity(ActivityClientRecord r, final Activity activity) {
...
//创建Activity的Context
ContextImpl appContext = ContextImpl.createActivityContext(
this, r.packageInfo, r.token, displayId, r.overrideConfig);
appContext.setOuterContext(activity);
Context baseContext = appContext;
...
return baseContext;
}
通过以上代码的分析,我们找到Context
的实现类就是ContextImpl
,我们继续跟踪ContextImpl
类的getSystemService(String key)
,代码如下:
@Override
public Object getSystemService(String name) {
return SystemServiceRegistry.getSystemService(this, name);
}
SystemServiceRegistry分析
从这个类的名字我们可以发现,这个类貌似就是注册服务的,实际上这个类中一个静态代码块,来注册各种服务,代码如下:
static {
...
//蓝牙服务
registerService(Context.BLUETOOTH_SERVICE, BluetoothManager.class,
new CachedServiceFetcher<BluetoothManager>() {
@Override
public BluetoothManager createService(ContextImpl ctx) {
return new BluetoothManager(ctx);
}});
//剪切板服务
registerService(Context.CLIPBOARD_SERVICE, ClipboardManager.class,
new CachedServiceFetcher<ClipboardManager>() {
@Override
public ClipboardManager createService(ContextImpl ctx) {
return new ClipboardManager(ctx.getOuterContext(),
ctx.mMainThread.getHandler());
}});
//电池服务
registerService(Context.BATTERY_SERVICE, BatteryManager.class,
new StaticServiceFetcher<BatteryManager>() {
@Override
public BatteryManager createService() {
return new BatteryManager();
}});
//NFC服务
registerService(Context.NFC_SERVICE, NfcManager.class,
new CachedServiceFetcher<NfcManager>() {
@Override
public NfcManager createService(ContextImpl ctx) {
return new NfcManager(ctx);
}});
//布局填充LayoutInflater服务
registerService(Context.LAYOUT_INFLATER_SERVICE, LayoutInflater.class,
new CachedServiceFetcher<LayoutInflater>() {
@Override
public LayoutInflater createService(ContextImpl ctx) {
return new PhoneLayoutInflater(ctx.getOuterContext());
}});
//WIFI服务
registerService(Context.WIFI_SERVICE, WifiManager.class,
new CachedServiceFetcher<WifiManager>() {
@Override
public WifiManager createService(ContextImpl ctx) {
IBinder b = ServiceManager.getService(Context.WIFI_SERVICE);
IWifiManager service = IWifiManager.Stub.asInterface(b);
return new WifiManager(ctx.getOuterContext(), service,
ConnectivityThread.getInstanceLooper());
}});
//窗口服务
registerService(Context.WINDOW_SERVICE, WindowManager.class,
new CachedServiceFetcher<WindowManager>() {
@Override
public WindowManager createService(ContextImpl ctx) {
return new WindowManagerImpl(ctx);
}});
//相机服务
registerService(Context.CAMERA_SERVICE, CameraManager.class,
new CachedServiceFetcher<CameraManager>() {
@Override
public CameraManager createService(ContextImpl ctx) {
return new CameraManager(ctx);
}});
//网络状态服务
registerService(Context.NETWORK_STATS_SERVICE, NetworkStatsManager.class,
new CachedServiceFetcher<NetworkStatsManager>() {
@Override
public NetworkStatsManager createService(ContextImpl ctx) {
return new NetworkStatsManager(ctx.getOuterContext());
}});
...等等
}
以上静态代码块在该类第一次加载时执行,且只执行一次,保证实例唯一性。以上服务就包含了布局填充器服务LayoutInflater Service
。看下如何获取
private static final HashMap<Class<?>, String> SYSTEM_SERVICE_NAMES =
new HashMap<Class<?>, String>();
//Service缓存容器
private static final HashMap<String, ServiceFetcher<?>> SYSTEM_SERVICE_FETCHERS =
new HashMap<String, ServiceFetcher<?>>();
//注册服务器
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);
}
//获取Service
@Override
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;
}
通过ContextImpl
类的分析,我们知道将服务以键值对的形式存储在一个hashMap
中,用户使用时只需要根据key来获取到对应的ServiceFetcher
,然后通过调用ServiceFetcher
的getService
方法来获取具体的的服务对象。以上便达到了单例的效果。