1、概述
平时我们在开发Android应用时,会经常用到的一项操作就是获取系统服务,也许这样说大家不是很清楚,我们来看一个简单的示例1。
LayoutInflater inflater = (LayoutInflater)getSystemService(LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.home_select_list, null);
在加载一个自定义的View时我们都是这样使用的,这就是通过系统服务来获得加载布局的对象,还有很多的服务都是通过Context.getSystemService()方法来获取相应的对象。
好啦话不多说,我们来详细的分析一下这些系统服务是如何获得的。
2、不同系统服务获取方式
首先我们要知道这个getSystemService()方法是在什么地方定义和被实现的,其定义在Context类,而实现是在ContextImpl类中,如果大家对它们关系不是很熟悉的话可以看一下另外一篇文章Android中ContextImpl源码分析(二)。我们进入到ContextImpl.getSystemService()方法中。
private static final HashMap<String, ServiceFetcher> SYSTEM_SERVICE_MAP =
new HashMap<String, ServiceFetcher>();
public Object getSystemService(String name) {
ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name);
return fetcher == null ? null : fetcher.getService(this);
}
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;
}
}
//getService中调用createService方法
service = createService(ctx);
cache.set(mContextCacheIndex, service);
return service;
}
}
//用于子类重写
public Object createService(ContextImpl ctx) {
throw new RuntimeException("Not implemented");
}
这个方法只是用于获取相关的系统服务,而真正注册系统服务的方法如下:
private static void registerService(String serviceName, ServiceFetcher fetcher) {
if (!(fetcher instanceof StaticServiceFetcher)) {
fetcher.mContextCacheIndex = sNextPerContextServiceCacheIndex++;
}
//将相关服务都保存到HashMap中
SYSTEM_SERVICE_MAP.put(serviceName, fetcher);
}
这里我们介绍完了如何注册和获取相关服务,接下来我们将介绍常用的几个服务的注册方式。
1、LayoutInflater获取分析
registerService(LAYOUT_INFLATER_SERVICE, new ServiceFetcher() {
public Object createService(ContextImpl ctx) {
return PolicyManager.makeNewLayoutInflater(ctx.getOuterContext());
}});
其直接将操作转给PolicyManager的makeNewLayoutInflater方法进行处理,我们进入该方法。
public final class PolicyManager {
public static LayoutInflater makeNewLayoutInflater(Context context) {
return sPolicy.makeNewLayoutInflater(context);
}
}
makeNewLayoutInflater方法将操作转给Policy.makeNewLayoutInflater方法,进入该方法。
public class Policy implements IPolicy {
public LayoutInflater makeNewLayoutInflater(Context context) {
//最终返回一个PhoneLayoutInflater对象
return new PhoneLayoutInflater(context);
}
}
最终创建一个PhoneLayoutInflater对象,该对象是LayoutInflater的子类,到此LayoutInflater就分析结束啦,如果大家想看具体的流程请看这篇博文SetContentView与LayoutInflater源码分析。
2、ActivityManagerService获取分析
registerService(ACTIVITY_SERVICE, new ServiceFetcher() {
public Object createService(ContextImpl ctx) {
//直接返回
return new ActivityManager(ctx.getOuterContext(), ctx.mMainThread.getHandler());
}});
用于直接创建ActivityManager对象并返回,我们进入ActivityManager系统源码。
public class ActivityManager {
public List<RunningAppProcessInfo> getRunningAppProcesses() {
try {
return ActivityManagerNative.getDefault().getRunningAppProcesses();
} catch (RemoteException e) {
return null;
}
}
//......
}
其实你会发现ActivityManager中的绝大部分方法都是调用ActivityManagerNative.getDefault()方法,我们进入该方法的源码。
public abstract class ActivityManagerNative extends Binder implements IActivityManager
{
static public IActivityManager getDefault() {
return gDefault.get();
}
private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
protected IActivityManager create() {
IBinder b = ServiceManager.getService("activity");
IActivityManager am = asInterface(b);
return am;
}
};
//asInterface返回的是AMS的代理对象ActivityManagerProxy
static public IActivityManager asInterface(IBinder obj) {
if (obj == null) {
return null;
}
IActivityManager in =
(IActivityManager)obj.queryLocalInterface(descriptor);
if (in != null) {
return in;
}
//最终返回一个ActivityManager的代理对象
return new ActivityManagerProxy(obj);
}
}
通过ActivityManagerProxy这个代理对象我们就可以间接的和ActivityManagerService进行通信,代理对象Proxy会调用mRemote.transact()方法,此时的mRemote对象即ActivityManagerService,然后调用AMS的onTransact方法,这里可以从Binder类的transact方法看出。
public final boolean transact(int code, Parcel data, Parcel reply,
int flags) throws RemoteException {
if (data != null) {
data.setDataPosition(0);
}
//这里调用onTransact方法
boolean r = onTransact(code, data, reply, flags);
if (reply != null) {
reply.setDataPosition(0);
}
return r;
}
可以看出在Binder类的transact方法中调用了onTransact方法,紧接着我们进入AMS的onTransact方法。
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
//......
return super.onTransact(code, data, reply, flags);
}
可以发现AMS的onTransact方法又调用父类的onTransact方法,其父类是ActivityManagerNative,所以进入AMN的onTransact方法并找到对应的识别码,进而调用子类即AMS的相关方法完成操作,看起来关系好像还挺复杂的,其实一点都不复杂,我们用一张类结构图来表示其相关关系。
到此AMS的相关类就分析完毕啦,但是也许此刻你心里还不是很清楚他们之前的调用关系,我们在结合源码的流程后重新绘制一张ActivityManager的运行机制。
到此AMS的获取和调用流程我们就简单的分析完毕啦,如果大家还不是很明白的可以去看一下另外一篇专门分析AMS的文章ActivityManagerService与应用程序通信分析。
3、PackageManagerService获取分析
我们在来看一下PKMS是怎样获取的,首先还是从ContextImpl类入手。
private PackageManager mPackageManager;
public PackageManager getPackageManager() {
if (mPackageManager != null) {
return mPackageManager;
}
//这里我们进入ActivityThread.getPackageManager()
IPackageManager pm = ActivityThread.getPackageManager();
if (pm != null) {
//创建ApplicationPackageManager对象
return (mPackageManager = new ApplicationPackageManager(this, pm));
}
return null;
}
我们首先进入ActivityThread.getPackageManager()方法看其源码。
static IPackageManager sPackageManager;
public static IPackageManager getPackageManager() {
if (sPackageManager != null) {
return sPackageManager;
}
//获取PKMS对象
IBinder b = ServiceManager.getService("package");
//获取PKMS的代理对象Proxy
sPackageManager = IPackageManager.Stub.asInterface(b);
return sPackageManager;
}
在这里在进入IPackageManager.Stub.asInterface()方法,看是如何获取Proxy的代理对象的。
public static android.content.pm.IPackageManager asInterface(android.os.IBinder obj)
{
if ((obj==null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof android.content.pm.IPackageManager))) {
return ((android.content.pm.IPackageManager)iin);
}
//这里返回PKMS的Proxy对象
return new android.content.pm.IPackageManager.Stub.Proxy(obj);
}
接下来我们在回到getPackageManager()方法中,在方法的最后创建了ApplicationPackageManager对象,并将PKMS的Proxy对象作为参数传递过去。
ApplicationPackageManager(ContextImpl context,
IPackageManager pm) {
mContext = context;
//这里的mPM对象就是之前创建的PKMS的代理对象Proxy
mPM = pm;
}
我们用一张图来表示PKMS相关类的关系。
好啦,PKMS的获取我们就简单的介绍到这里啦,大家如果想了解的更详细可以去看我的另外一篇文章PackageManagerService源码分析之入门(一)。
4、WindowManagerService获取分析
我们首先还是在ContextImpl类中找到其对于的注册源码。
registerService(WINDOW_SERVICE, new ServiceFetcher() {
Display mDefaultDisplay;
public Object getService(ContextImpl ctx) {
Display display = ctx.mDisplay;
if (display == null) {
if (mDefaultDisplay == null) {
DisplayManager dm = (DisplayManager)ctx.getOuterContext().
getSystemService(Context.DISPLAY_SERVICE);
mDefaultDisplay = dm.getDisplay(Display.DEFAULT_DISPLAY);
}
display = mDefaultDisplay;
}
//创建WindowManagerImpl对象
return new WindowManagerImpl(display);
}});
我们可以发现在获取WindowManager时,其获取的是WindowManager的子类WindowManagerImpl对象,我们在进入WindowManagerImpl类中。
public final class WindowManagerImpl implements WindowManager {
private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance();
public WindowManagerImpl(Display display) {
this(display, null);
}
//......
}
发现其将所有的操作都转给了WindowManagerGlobal对象进行处理,我们在进入WindowManagerGlobal对象中。
public final class WindowManagerGlobal {
//观察其是如何获取WMS对象
public static IWindowManager getWindowManagerService() {
synchronized (WindowManagerGlobal.class) {
if (sWindowManagerService == null) {
//通过IWindowManager.Stub.asInterface()方法来得到WMS对象
sWindowManagerService = IWindowManager.Stub.asInterface(
ServiceManager.getService("window"));
sWindowManagerService = getWindowManagerService();
}
return sWindowManagerService;
}
}
}
在WindowManagerGlobal对象中我们只关注是如何获取WMS服务的,其通过IWindowManager.Stub.asInterface()方法来获得,和我们之前分析其他Service的获取方式大同小异,我们简单的看一下。
public interface IWindowManager extends android.os.IInterface{
public static abstract class Stub extends android.os.Binder implements android.view.IWindowManager{
public static android.view.IWindowManager asInterface(android.os.IBinder obj)
{
if ((obj==null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof android.view.IWindowManager))) {
return ((android.view.IWindowManager)iin);
}
//创建WMS的代理对象Proxy
return new android.view.IWindowManager.Stub.Proxy(obj);
}
//WMS的代理对象Proxy
private static class Proxy implements android.view.IWindowManager
{
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote)
{
mRemote = remote;
}
}
}
}
到此大家就应该明白客户端是如何通过WMS的代理对象Proxy与WMS进行通信的吧,好啦,我们话不多说如果大家还想深入的了解一下WMS,可以参考另外一篇博文WindowManagerService和应用程序的IPC过程。
5、UsbService获取分析
我们直接从ContextImpl类入手。
registerService(USB_SERVICE, new ServiceFetcher() {
public Object createService(ContextImpl ctx) {
//获取UsbService对象
IBinder b = ServiceManager.getService(USB_SERVICE);
//创建UsbManager对象
return new UsbManager(ctx, IUsbManager.Stub.asInterface(b));
}});
这里主要从两个方面介绍:
(1)何时我们将UsbService添加到ServiceManager中
(2)如何创建UsbService的代理对象
首先我们看一下在哪里将UsbService添加到ServiceManager中。
private static final String USB_SERVICE_CLASS =
"com.android.server.usb.UsbService$Lifecycle";
mSystemServiceManager.startService(USB_SERVICE_CLASS);
在SystemServer中通过注册和启动UsbService的内部类Lifecycle,从而在ServiceManager中注册UsbService,这里大家可以参考USBService源码分析(一)这篇文章。
我们在进入IUsbManager.Stub.asInterface(b)方法中。
public interface IUsbManager extends android.os.IInterface
{
public static abstract class Stub extends android.os.Binder implements android.hardware.usb.IUsbManager
{
public static android.hardware.usb.IUsbManager asInterface(android.os.IBinder obj)
{
if ((obj==null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof android.hardware.usb.IUsbManager))) {
return ((android.hardware.usb.IUsbManager)iin);
}
//创建UsbService的代理对象
return new android.hardware.usb.IUsbManager.Stub.Proxy(obj);
}
}
}
好啦,看到这里相信大家对UsbService的代理模式应该也了解了,我们这里看一张图。
首先UsbManager是Android系统提供给外界访问Usb的一个入口,而IUsbManager.Stub.Proxy则是USBService的一个代理服务,其最终实现都在UsbService中,可以从以下博文中查看详细的UsbService分析USBService源码分析(一)。