一、Application层
App开发时,我们都是通过this.getSystemService语句获取系统服务的,如:
ActivityManager am=(ActivityManager)this.getSystemService(ACTIVITY_SERVICE);
所以,我们以ActivityManager为例,从api入手看看这个服务是从哪来的。然而,当我们一层一层往下追踪代码时,却发现最终是个抽象类Context的抽象方法。
public abstract class Context {
public abstract Object getSystemService(String name);
}
所以现在关键在于找到Context的实现类。不过,光靠api是找不到该实现类的,只能在Android的源码framework中找寻,实际上,该实现类就是ContextImpl.java,其路径是:
frameworks/base/core/java/android/app/ContextImpl.java
private static final HashMap<String, ServiceFetcher> SYSTEM_SERVICE_MAP =
new HashMap<String, ServiceFetcher>();
@Override
public Object getSystemService(String name) {
ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name);
return fetcher == null ? null : fetcher.getService(this);
}
SYSTEM_SERVICE_MAP集合有get,那么肯定有put元素的地方,而这个地方是:
private static void registerService(String serviceName, ServiceFetcher fetcher) {
if (!(fetcher instanceof StaticServiceFetcher)) {
fetcher.mContextCacheIndex = sNextPerContextServiceCacheIndex++;
}
SYSTEM_SERVICE_MAP.put(serviceName, fetcher);
}
我们可以看到这个函数的功能就是注册服务。而使用这个函数的地方是该类的static代码块,当加载该类时是会优先加载静态块内的内容,如:
static {
registerService(ACTIVITY_SERVICE, new ServiceFetcher() {
public Object createService(ContextImpl ctx) {
return new ActivityManager(ctx.getOuterContext(), ctx.mMainThread.getHandler());
}});
}
再看看内部类fetcher
static class ServiceFetcher {
public Object getService(ContextImpl ctx) {
ArrayList<Object> cache = ctx.mServiceCache;
Object service;
synchronized (cache) {
if (cache.size() == 0) {
for (int i = 0; i < sNextPerContextServiceCacheIndex; i++) {
cache.add(null);
}
} else {
service = cache.get(mContextCacheIndex);
if (service != null) {
return service;
}
}
service = createService(ctx);//
cache.set(mContextCacheIndex, service);
return service;
}
}
}
因此,只要有加载ContextImpl类时,Application层就可以通过getSystemService获取该要的服务。
二、系统进程
现在我们能明白,从Application到Framework层,是怎样的一个过程。
不过,ActtivityManager是从哪来的?是什么时候创建的?所谓系统服务,猜想都应该是系统启动之时也一并创建和启动的。所以我们试着从android系统启动程序找起。
在android系统中所有应用程序进程和服务都是由zygote进程加载生成的,其中最为重要的一个进程systemserver,就是我们要重点查看的。其代码路径为:
frameworks/base/services/java/com/android/server/SystemServer.java
该文件下有两个类SystemServer和ServerThread。在SystemServer的main方法中执行了ServerThread.initAndLoop()方法。
public static void main(String[] args) {
// This used to be its own separate thread, but now it is
// just the loop we run on the main thread.
ServerThread thr = new ServerThread();
thr.initAndLoop();
}
initAndLoop()方法代码很长,不过我只要找到有关ActivityManager就可以了。有一行代码是这样的:
public void initAndLoop() {
ActivityManagerService.setSystemProcess();
}
实际上,这一步的代码如下:
public static void setSystemProcess() {
try {
ActivityManagerService m = mSelf;
ServiceManager.addService(Context.ACTIVITY_SERVICE, m, true);
...
}catch(){
...
}
(ActivityManagerService的路径为:
frameworks/base/services/java/com/android/server/am/ActivityManagerServcie.java)
而ServiceManager类,路径为:
KK/frameworks/base/core/java/android/os/ServiceManager.java
public final class ServiceManager {
public static void addService(String name, IBinder service) {
try {
getIServiceManager().addService(name, service, false);
} catch (RemoteException e) {
Log.e(TAG, "error in addService", e);
}
}
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}
// Find the service manager
sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());//
return sServiceManager;
}
}
这样,或多或少可以明白,获取的服务实际上在系统启动一开始就已经addService添加进来了,而ContextImpl再通过registerService注册服务,以此便于应用层的调用。
其实,从Application层获取的服务是Binder服务经过封装之后提供的服务,而ActivityManager就是ActivityManagerService的封装类。具体是怎样的过程,是涉及到Ibinder机制以及aidl相关知识,这里不是我们关注的重点。
后记:我所查询的代码,是Android4.4,且是公司实际的智能电视工程项目,所以很可能会不一样,比如说是路径或是代码。还有,该博客很多是我个人看源码的理解,也许会有很多错误,希望大家可以见谅。
本文详细探讨了Android系统服务的调用过程,从Application层如何通过getSystemService获取系统服务,如ActivityManager,到Framework层的ContextImpl类如何注册服务。在系统启动时,systemserver进程创建并启动服务,ServiceManager负责管理这些服务。服务实际上是封装后的Binder服务,涉及Ibinder和AIDL机制。博客基于Android4.4和智能电视工程项目的源码进行分析,可能存在差异和理解误差。

被折叠的 条评论
为什么被折叠?



