Android中常见的系统服务

时间:2021-10-14 07:36:15

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的相关方法完成操作,看起来关系好像还挺复杂的,其实一点都不复杂,我们用一张类结构图来表示其相关关系。

Android中常见的系统服务

到此AMS的相关类就分析完毕啦,但是也许此刻你心里还不是很清楚他们之前的调用关系,我们在结合源码的流程后重新绘制一张ActivityManager的运行机制。

Android中常见的系统服务

到此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相关类的关系。

Android中常见的系统服务

好啦,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的代理模式应该也了解了,我们这里看一张图。

Android中常见的系统服务

首先UsbManager是Android系统提供给外界访问Usb的一个入口,而IUsbManager.Stub.Proxy则是USBService的一个代理服务,其最终实现都在UsbService中,可以从以下博文中查看详细的UsbService分析USBService源码分析(一)