赞
踩
在平时的android开发中,我们经常会通过Context来获取系统服务,比如ActivityManagerService,AccountManagerService等系统服务,今天我们就来看下getSystemService(String name)的整个调用流程。
##找到Context的实现类##
打开Context类,可以看到Context是一个抽象类,那么getSystemService一定是在其实现类来调用的,具体我们都猜得到ContextImpl
public abstract class Context {
......
}
为什么是ContextImpl呢?我们都知道当我们启动一个Activity的时候,其实是在ActivityThread#performLaunchActivity方法中启动的,这一点可以参考上一篇文章" Activity启动流程 ",一个Activity的入口是
ActivityThread的main方法,看下main方法
public static void main(String[] args) { ....... // 主线程消息循环 Looper.prepareMainLooper(); ActivityThread thread = new ActivityThread(); thread.attach(false); if (sMainThreadHandler == null) { sMainThreadHandler = thread.getHandler(); } Looper.loop(); throw new RuntimeException("Main thread loop unexpectedly exited"); }
可以看到上面在main方法中,调用了自身的attach方法。
private void attach(boolean system) {
........
if (!system) {
final IActivityManager mgr = ActivityManagerNative.getDefault();
try {
// 通过binder获取到的ActivityManagerService关联当前mAppThread
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
// Ignore
}
}
可以看到在main方法中,通过调用activityThread的attach方法,并且参数为false,表示非系统应用,会通过binder与
ActivityManagerService通信,并且最后会调用performLaunchActivity方法。
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { Activity activity = null; try { java.lang.ClassLoader cl = r.packageInfo.getClassLoader(); activity = mInstrumentation.newActivity( cl, component.getClassName(), r.intent); r.intent.setExtrasClassLoader(cl); r.intent.prepareToEnterProcess(); if (r.state != null) { r.state.setClassLoader(cl); } } catch (Exception e) { .... } try { Application app = r.packageInfo.makeApplication(false, mInstrumentation); if (activity != null) { // 创建Context的实例 Context appContext = createBaseContextForActivity(r, 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); ....... } r.paused = true; mActivities.put(r.token, r); } catch (SuperNotCalledException e) { ..... } return activity; }
可以看到创建Context的具体实现是在ActivityThread#createBaseContextForActivity方法中完成的
private Context createBaseContextForActivity(ActivityClientRecord r, final Activity activity) {
// 可以看到这里创建的具体实例是ContextImpl
ContextImpl appContext = ContextImpl.createActivityContext(
this, r.packageInfo, displayId, r.overrideConfig);
appContext.setOuterContext(activity);
Context baseContext = appContext;
......
return baseContext;
}
好了,到现在位置我们可以看到Context的实现类就是ContextImpl,那么关于getSystemService的具体实现也应该在ContextImpl里面了。
##getSystemService的具体实现##
ContextImpl#getSystemService的实现如下
@Override
public Object getSystemService(String name) {
return SystemServiceRegistry.getSystemService(this, name);
}
可以看到实际上ContextImpl也是通过SystemServiceRegistry.getSystemService来获取具体的服务,那么下面看看SystemServiceRegistry.getSystemService
public static Object getSystemService(ContextImpl ctx, String name) {
ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name);
return fetcher != null ? fetcher.getService(ctx) : null;
}
private static final HashMap<String, ServiceFetcher<?>> SYSTEM_SERVICE_FETCHERS =
new HashMap<String, ServiceFetcher<?>>();
可看到实际上获取系统服务是通过ServiceFetcher的getService来获取的,并且SYSTEM_SERVICE_FETCHERS实际上就是一个Map实例,所以肯定是通过put方法为它赋值的。通过搜索,我们发现只有一个地方在做put操作:
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);
}
顾名思义,这个方法是用来注册系统服务的,当注册系统服务的时候,就会调用到SYSTEM_SERVICE_FETCHERS.put(serviceName, serviceFetcher);将当前的服务put到SYSTEM_SERVICE_NAMES集合中
static abstract interface ServiceFetcher<T> {
T getService(ContextImpl ctx);
}
ServiceFetcher是一个接口,又三个实现类:CachedServiceFetcher,StaticServiceFetcher,StaticOuterContextServiceFetcher,具体不同的服务可能对应不同的实现类
这些系统服务都是在SystemServiceRegistry的static静态代码块中进行注册的,如下:
static { ..... registerService(Context.ACCOUNT_SERVICE, AccountManager.class, new CachedServiceFetcher<AccountManager>() { @Override public AccountManager createService(ContextImpl ctx) { IBinder b = ServiceManager.getService(Context.ACCOUNT_SERVICE); IAccountManager service = IAccountManager.Stub.asInterface(b); return new AccountManager(ctx, service); }}); registerService(Context.ACTIVITY_SERVICE, ActivityManager.class, new CachedServiceFetcher<ActivityManager>() { @Override public ActivityManager createService(ContextImpl ctx) { return new ActivityManager(ctx.getOuterContext(), ctx.mMainThread.getHandler()); }}); ..... }
这里,我们以ActivityManagerService为例来进行学习。在注册该服务的时候,将Context.ACTIVITY_SERVICE作为键,将CachedServiceFetcher作为值,并且重写了createService方法,createService是在当前ServiceFetcher的
getService里执行的,这里会返回一个ActivityManager的实例,ctx.mMainThread.getHandler()就是ActivityThread中的H,在"activity 启动流程"一文,我们已经知道了,启动activity最终就会通过ActivityThread$H的handleMessage进行处理,实际上,包括service的启动以及Broadcast的处理都是在H里处理的,这个后面会细说。
##在SystemServer中启动系统服务##
我们知道android系统第一次开机的时候,会通过ZygoteInit来启动SystemServer,简单看下ZygoteInit#main方法
public static void main(String argv[]) { try { boolean startSystemServer = false; for (int i = 1; i < argv.length; i++) { // 通过系统传递过来的命令来判断是否需要启动运行SystemServer类 if ("start-system-server".equals(argv[i])) { startSystemServer = true; } } if (startSystemServer) { // 启动运行SystemServer类 startSystemServer(abiList, socketName); } } }
此时会执行SystemServer的main方法
public static void main(String[] args) {
new SystemServer().run();
}
比较简单,内部运行自身的run方法
private void run() { // 如果当前系统时间小于1970年,则设置为1970 if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) { SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME); } // 设置默认的语言和地区 if (!SystemProperties.get("persist.sys.language").isEmpty()) { final String languageTag = Locale.getDefault().toLanguageTag(); SystemProperties.set("persist.sys.locale", languageTag); SystemProperties.set("persist.sys.language", ""); SystemProperties.set("persist.sys.country", ""); SystemProperties.set("persist.sys.localevar", ""); } // Mmmmmm... more memory! VMRuntime.getRuntime().clearGrowthLimit(); // The system server has to run all of the time, so it needs to be // as efficient as possible with its memory usage. VMRuntime.getRuntime().setTargetHeapUtilization(0.8f); // Prepare the main looper thread (this thread). android.os.Process.setThreadPriority( android.os.Process.THREAD_PRIORITY_FOREGROUND); android.os.Process.setCanSelfBackground(false); Looper.prepareMainLooper(); // Initialize native services. System.loadLibrary("android_servers"); // Check whether we failed to shut down last time we tried. // This call may not return. performPendingShutdown(); // Initialize the system context. createSystemContext(); // Create the system service manager. mSystemServiceManager = new SystemServiceManager(mSystemContext); LocalServices.addService(SystemServiceManager.class, mSystemServiceManager); // 启动服务 try { startBootstrapServices(); startCoreServices(); startOtherServices(); } catch (Throwable ex) { throw ex; } // Loop forever. Looper.loop(); throw new RuntimeException("Main thread loop unexpectedly exited"); }
在上面的run方法中,和service相关的操作主要就是通过下面的方法启动:开机,核心,以及其他服务
startBootstrapServices();
startCoreServices();
startOtherServices();
其实在这个三个start服务中,不止启动系统服务,还会将这些服务和ServiceManager进行关联,以方便ServiceManager的管理
比如:
ServiceManager.addService(Context.INPUT_SERVICE, inputManager);
好了,到这里为止,getSystemService的流程就走完了,作为自己的学习记录。如果又不对的地方,敬请指教。
欢 迎 关 注 我 的 公 众 号 “编 程 大 全”
专注技术分享,包括Java,python,AI人工智能,Android分享,不定期更新学习视频
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。