Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >图解 | 一图摸清Android系统服务

图解 | 一图摸清Android系统服务

作者头像
Holiday
发布于 2020-10-29 02:03:49
发布于 2020-10-29 02:03:49
80400
代码可运行
举报
文章被收录于专栏:哈利迪ei哈利迪ei
运行总次数:0
代码可运行

一图摸清Android系统服务的获取和注册流程~

大纲:

  • 获取系统服务
  • 注册系统服务
    • 独立进程的服务
    • 非独立进程的服务
  • 总结
  • 参考资料

本文约1.9k字,阅读大约8分钟。 Android源码基于8.0。

先预览下整体流程~

开始分析!

获取系统服务

在日常开发中,可以通过Context.getSystemService()在自己的应用程序里获取到系统服务:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//ContextImpl.java
public Object getSystemService(String name) {
    //SystemServiceRegistry是系统服务的注册表,用来集中管理系统服务
    return SystemServiceRegistry.getSystemService(this, name);
}

//SystemServiceRegistry.java
public static Object getSystemService(ContextImpl ctx, String name) {
    //根据服务名字从HashMap中取出ServiceFetcher
    ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name);
    //传入上下文,借助ServiceFetcher来获取系统服务
    return fetcher != null ? fetcher.getService(ctx) : null;
}

ServiceFetcher是一个抽象接口,抽象类CachedServiceFetcher实现了他,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//CachedServiceFetcher.java
public final T getService(ContextImpl ctx) {
    //每个上下文ctx都有一份系统服务缓存
    final Object[] cache = ctx.mServiceCache;
    synchronized (cache) {
        //从缓存里获取系统服务
        Object service = cache[mCacheIndex];
        if (service == null) {
            //缓存里没有,则创建
            service = createService(ctx);
            //存入缓存
            cache[mCacheIndex] = service;
        }
        return (T)service;
    }
}

//createService是个抽象方法
public abstract T createService(ContextImpl ctx);

在SystemServiceRegistry里有个静态代码块static{}会“注册服务”,从中实现抽象方法createService()的逻辑,以电源服务PowerManager为例,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//SystemServiceRegistry.java
registerService(
    Context.POWER_SERVICE, PowerManager.class,
    new CachedServiceFetcher<PowerManager>() {
        @Override
        public PowerManager createService(ContextImpl ctx){
            //ServiceManager根据服务名字获取系统服务的Binder对象
            IBinder b = ServiceManager.getServiceOrThrow(Context.POWER_SERVICE);
            //将服务端的Binder转成客户端所需的AIDL接口类型的对象IPowerManager
            IPowerManager service = IPowerManager.Stub.asInterface(b);
            //再用PowerManager类包一层,方便外部使用
            return new PowerManager(ctx.getOuterContext(),
                                    service, 
                                    ctx.mMainThread.getHandler());
        }});

AIDL可以辅助生成用于binder通信的类,IPowerManager就是定义在IPowerManager.aidl里的,binder内部细节本文不做讨论。

ServiceManager的getServiceOrThrow()函数会调用getService(),

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//ServiceManager.java
public static IBinder getService(String name) {
    //取缓存
    IBinder service = sCache.get(name);
    if (service != null) {
        return service;
    } else {
        //取不到就继续,这里创建完并没有存入sCache,即sCache只是预置了一些启动阶段存入的服务
        //getService()获取系统服务的Binder对象,用allowBlocking包了一下,允许阻塞
        return Binder.allowBlocking(getIServiceManager().getService(name));
    }
    return null;
}

private static IServiceManager getIServiceManager() {
    if (sServiceManager != null) {
        return sServiceManager;
    }
    //binder跨进程通信:
    //BinderInternal.getContextObject()得到系统级别上下文的IBinder,可用来查找服务
    //asInterface将IBinder转成IServiceManager(本质是BpServiceManager)
    sServiceManager = ServiceManagerNative
        .asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
    return sServiceManager;
}

可见,我们的应用程序进程会通过binder跨进程通信,拿到ServiceManager进程的IServiceManager对象(本质是BpServiceManager),然后就可以通过IServiceManager对象的getService来获取系统服务了。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public interface IServiceManager extends IInterface{
    //从IServiceManager获取系统服务,如果服务不存在,会阻塞最多5秒,直到服务被发布注册
    public IBinder getService(String name);
}

看下IServiceManager的具体实现,在IServiceManager.cpp文件里,有个BpServiceManager类,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//class BpServiceManager : public BpInterface<IServiceManager>
//这里的BpInterface是binder内部的细节了,不是很理解,后面抽时间看看

virtual sp<IBinder> getService(const String16& name) const
{
    unsigned n;
    //如果获取不到,则休眠1秒再取,最多阻塞5秒
    for (n = 0; n < 5; n++){
        if (n > 0) {
            //休眠1秒,待会再取
            sleep(1);
        }
        sp<IBinder> svc = checkService(name);
        //获取到系统服务,则返回
        if (svc != NULL) return svc;
    }
    return NULL;
}

//返回系统服务的binder,暂不深究
virtual sp<IBinder> checkService( const String16& name) const
{
    //binder使用Parcelable来序列化数据
    Parcel data, reply;
    data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
    data.writeString16(name);
    //remote()得到BpBinder,transact发送请求
    remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply);
    return reply.readStrongBinder();//Binder
}

再梳理一下系统服务的获取过程:

  1. 应用程序进程调用getSystemService
  2. 通过binder跨进程通信,拿到ServiceManager进程的BpServiceManager对象
  3. 通过BpServiceManager获取到系统服务

注册系统服务

系统服务可以分成两大类:

一是有独立进程的ServiceManager、SurfaceFlinger等,他们在init进程启动时就会被fork创建

二是非独立进程的AMS、PMS、WMS等,他们在init进程fork出Zygote进程,Zygote进程fork出的SystemServer进程创建

独立进程的服务

独立进程的系统服务在init进程解析init.rc时启动,比如SurfaceFlinger,看下他的启动配置文件surfaceflinger.rc,

注:frameworks/native/services下列出了一系列服务,不过ServiceManager服务放在了frameworks/native/cmds/servicemanager目录下。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//frameworks/native/services/surfaceflinger/surfaceflinger.rc
service surfaceflinger /system/bin/surfaceflinger
    class core animation
    user system
    group graphics drmrpc readproc
    onrestart restart zygote

service以服务的形式来启动进程,surfaceflinger是进程名字,/system/bin/surfaceflinger是可执行程序的路径,该程序的入口函数main在main_surfaceflinger.cpp,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int main(int, char**) {
    //ProcessState会启动binder机制(打开binder驱动、映射内存、分配缓冲区)
    sp<ProcessState> ps(ProcessState::self());
    //启动binder线程
    ps->startThreadPool();

    //初始化surfaceflinger
    sp<SurfaceFlinger> flinger = new SurfaceFlinger();
    flinger->init();

    //发布注册surfaceflinger
    sp<IServiceManager> sm(defaultServiceManager());
    sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false);

    //在当前线程运行surfaceflinger
    flinger->run();
    return 0;
}

看下defaultServiceManager()的实现,在IServiceManager.cpp,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
sp<IServiceManager> defaultServiceManager()
{
    //有值,直接返回
    if (gDefaultServiceManager != NULL) return gDefaultServiceManager;

    {
        AutoMutex _l(gDefaultServiceManagerLock);
        while (gDefaultServiceManager == NULL) {
            //查找ServiceManager,强转为IServiceManager(本质是BpServiceManager)
            gDefaultServiceManager = interface_cast<IServiceManager>(
                ProcessState::self()->getContextObject(NULL));
            //如果IServiceManager还是null,则休眠1秒再取,直至取到才结束循环
            if (gDefaultServiceManager == NULL)
                sleep(1);
        }
    }

    return gDefaultServiceManager;
}

因为SurfaceFlinger进程和ServiceManager进程都是init进程启动的,有可能SurfaceFlinger在获取IServiceManager时,ServiceManager还没来得及注册,所以这里会边取边休眠,取到才结束循环。

得到IServiceManager后,执行sm->addService,在IServiceManager.cpp文件里有个BpServiceManager类,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//class BpServiceManager : public BpInterface<IServiceManager>
//这里的BpInterface是binder内部的细节了,不是很理解,后面抽时间看看

//注册系统服务(的binder),暂不深究
virtual status_t addService(const String16& name, const sp<IBinder>& service,
                            bool allowIsolated)
{
    //binder使用Parcelable来序列化数据
    Parcel data, reply;
    data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
    data.writeString16(name);
    data.writeStrongBinder(service);//Binder
    data.writeInt32(allowIsolated ? 1 : 0);
    //remote()得到BpBinder,transact发送请求
    status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
    return err == NO_ERROR ? reply.readExceptionCode() : err;
}

梳理一下:

  1. init进程解析init.rc配置fork出新的进程启动多项独立进程的系统服务,如SurfaceFlinger
  2. 执行SurfaceFlinger的可执行程序,找到ServiceManager进程的BpServiceManager对象
  3. 通过BpServiceManager执行addService注册服务

非独立进程的服务

非独立进程的系统服务由SystemServer进程启动,从图解Android系统的启动一文可知,SystemServer借助SystemServiceManager类(SSM)来启动系统服务,比如AMS,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//SystemServer.java
private void startBootstrapServices() {
    //AMS由SSM创建启动
    mActivityManagerService = mSystemServiceManager
        //创建并启动AMS服务
        .startService(ActivityManagerService.Lifecycle.class)
        //通过binder获取AMS服务
        .getService();

    //注册AMS
    mActivityManagerService.setSystemProcess();
}

看到ActivityManagerService,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//ActivityManagerService.java
public void setSystemProcess() {
    //注册AMS
    ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
}

调用了ServiceManager.addService()进行注册,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//ServiceManager.java
public static void addService(String name, IBinder service, boolean allowIsolated) {
    //跟前边一样,通过binder跨进程通信,拿到ServiceManager进程的BpServiceManager对象
    //调用BpServiceManager的addService
    getIServiceManager().addService(name, service, allowIsolated);
}

可见,无论是SystemServer进程启动的服务,还是init进程启动的运行在独立进程里的服务,最终都是走ServiceManager进程的BpServiceManager.addService进行集中注册。

总结

综上,不管是由init进程启动的独立进程的系统服务如SurfaceFlinger,还是由SystemServer进程启动的非独立进程的系统服务如AMS,都是在ServiceManager进程中完成注册和获取的,在跨进程通信上使用了Android的binder机制。

不过哈迪在工作中没怎么用过binder,所以他的内部细节就暂时不深入了,后面抽时间再看。

再回顾一下~

系列文章:

参考资料

  • csdn - servicemanager的客户端代理: BpServiceManager
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-10-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 哈利迪ei 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Android开发之漫漫长途 IX——彻底掌握Binder
该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,我会尽量按照先易后难的顺序进行编写该系列。该系列引用了《Android开发艺术探索》以及《深入理解Android 卷Ⅰ,Ⅱ,Ⅲ》中的相关知识,另外也借鉴了其他的优质博客,在此向各位大神表示感谢,膜拜!!!另外,本系列文章知识可能需要有一定Android开发基础和项目经验的同学才能更好理解,也就是说该系列文章面向的是Android中高级开发工程师。
LoveWFan
2018/08/07
5430
Android开发之漫漫长途 IX——彻底掌握Binder
【android开发】Android binder学习一:主要概念
要看得懂android代码,首先要了解binder机制。binder机制也是android里面比较难以理解的一块,这里记录一下binder的重要概念以及实现,作为备忘。部分内容来源于网上,如有侵权,请及时告知。 1.binder通信机制概述 binder通信是一种client-server的通信结构, 1.从表面上来看,是client通过获得一个server的代理接口,对server进行直接调用; 2.实际上,代理接口中定义的方法与server中定义的方法是一一对应的; 3.client调用某个代理接口中的
程序员互动联盟
2018/03/13
1K0
【android开发】Android binder学习一:主要概念
图解 | 一图摸清Android应用进程的启动
init进程fork出Zygote进程后,Zygote进程会创建一个服务端socket,等待AMS发起socket请求。
Holiday
2020/11/06
9670
ServiceManager是如何管理java层service的
ServiceManager是Binder机制的大管家,管理着android系统的各种Service。service向servicemanager注册,当client需要调用service时,先通过servicemanager查询到该service,client接着再与service通信。这些service有java层的,也有native层的。native层通过BpServiceManager/BnServiceManager实现的service与servicemanager的交互。这次打算聊一聊servicemanager管理java层service是如何实现的。
好好学习吧
2023/06/12
5510
Android开发之漫漫长途 Ⅷ——Android Binder(也许是最容易理解的)
该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,我会尽量按照先易后难的顺序进行编写该系列。该系列引用了《Android开发艺术探索》以及《深入理解Android 卷Ⅰ,Ⅱ,Ⅲ》中的相关知识,另外也借鉴了其他的优质博客,在此向各位大神表示感谢,膜拜!!!另外,本系列文章知识可能需要有一定Android开发基础和项目经验的同学才能更好理解,也就是说该系列文章面向的是Android中高级开发工程师。
LoveWFan
2018/08/07
6610
Android开发之漫漫长途 Ⅷ——Android Binder(也许是最容易理解的)
[Android][Framework] 添加系统服务
做系统开发,有时候需要自己定义一些接口供App使用, 同时为了方便维护管理,就会需要自己建立一个服务,把新的功能集中在一起。下面就是新建一个系统服务的基本步骤。
wOw
2020/01/20
1.1K0
[Android][Framework] 添加系统服务
做系统开发,有时候需要自己定义一些接口供App使用, 同时为了方便维护管理,就会需要自己建立一个服务,把新的功能集中在一起。下面就是新建一个系统服务的基本步骤。
wOw
2018/09/15
1.5K0
Android系统服务(SystemService)简介
我们在Android开发过程中经常会用到各种各样的系统管理服务,如进行窗口相关的操作会用到窗口管理服务WindowManager,进行电源相关的操作会用到电源管理服务PowerManager,还有很多其他的系统管理服务,如通知管理服务NotifacationManager、振动管理服务Vibrator、电池管理服务BatteryManager…… 这些Manager提供了很多对系统层的控制接口。对于App开发者,只需要了解这些接口的使用方式就可以方便的进行系统控制,获得系统各个服务的信息,而不需要了解这些接口的具体实现方式。而对于Framework开发者,则需要了解这些Manager服务的常用实现模式,维护这些Manager的接口,扩展这些接口,或者实现新的Manager。
233333
2020/03/18
1.9K0
APK安装流程详解3——PackageManager与PackageManagerService
上面一篇文章介绍了PackageManager,我们知道PackageManager是一个抽象类,它里面很重要的方法都是抽象的,所以在具体执行的时候,肯定是他的实现子类,那么我们就来看下他具体实现类,上面一篇文章我们研究PackageManager类的时候,官网推荐获取PackageManager对象的方法是Context的Context#getPackageManager()方法,那我们来看下
隔壁老李头
2018/08/30
2.1K0
APK安装流程详解3——PackageManager与PackageManagerService
如何实现一个 System Services?
《Android 系统开发做什么?》写到 Android System Services 是专注于特定功能的模块化组件,应用框架 API 所提供的功能可与系统服务通信,以访问底层硬件。Android System Services 是如何写的?来以DisplayManagerService 为例,具体来看看。
吴小龙同學
2021/12/20
1.2K0
如何实现一个 System Services?
Android系统架构开篇
本文作为Android系统架构的开篇,起到提纲挈领的作用,从系统整体架构角度概要讲解Android系统的核心技术点,带领大家初探Android系统全貌以及内部运作机制。虽然Android系统非常庞大且错综复杂,需要具备全面的技术栈,但整体架构设计清晰。Android底层内核空间以Linux Kernel作为基石,上层用户空间由Native系统库、虚拟机运行环境、框架层组成,通过系统调用(Syscall)连通系统的内核空间与用户空间。对于用户空间主要采用C++和Java代码编写,通过JNI技术打通用户空间的Java层和Native层(C++/C),从而连通整个系统。
刘盼
2019/05/17
4K0
Android系统架构开篇
Android插件化原理解析——Hook机制之Binder Hook
Android系统通过Binder机制给应用程序提供了一系列的系统服务,诸如ActivityManagerService,ClipboardManager, AudioManager等;这些广泛存在系统服务给应用程序提供了诸如任务管理,音频,视频等异常强大的功能。
weishu
2018/09/05
1.9K0
Binder: ServiceManager的获取
我们以MediaService为例,来看下service的注册过程。MediaService对应的启动文件在main_mediaserver.cpp中的main方法。
Rouse
2021/01/27
6780
系统中的大管家—SystemServer进程
上篇说到Android系统的启动流程,Zygote进程fork的第一个进程就是SystemServer进程。
码上积木
2021/01/12
5680
Android内存泄漏:谨慎使用getSystemService
Android中有很多服务,比如PowerManager,AlarmManager,NotificationManager等,通常使用起来也很方便,就是使用Context.getSystemService方法来获得。
技术小黑屋
2018/09/05
1.3K0
Android内存泄漏:谨慎使用getSystemService
架构·微服务架构·ANDROID 源码分析(二)
上一篇的文章架构·微服务架构详细描述微服务架构相关的理论基础,为这一篇文章打好了理论基础。这篇文章将站在 Android Framework 设计者的角度上,剖析在 Android 中应用的微服务架构。
幺鹿
2018/08/21
7040
架构·微服务架构·ANDROID 源码分析(二)
Android窗口管理分析(2):WindowManagerService窗口管理之Window添加流程
之前分析说过,WindowManagerService只负责窗口管理,并不负责View的绘制跟图层混合,本文就来分析WMS到底是怎么管理窗口的。初接触Android时感觉:Activity似乎就是Google封装好的窗口,APP只要合理的启动新的Activity就打开了新窗口,这样理解没什么不对,Activity确实可以看做一种窗口及View的封装,不过从源码来看,Activity跟Window还是存在不同。本文主要从窗口的添加流程来将APP端、WMS端、SurfaceFlinger端三块串联起来,主要说一
看书的小蜗牛
2018/06/29
3K0
Android系统之System Server大纲
System Server是android 基本服务的提供者,是android系统运行的最基本需求,所有server运行在一个叫system_process的进程中,system_process进程是android java虚拟机跑的第一个进程,从Zygote 创建而来,是andorid系统最重要的java虚拟机。可以说,整个android系统的业务都是围绕system server而展开,所以,当system_process死掉了,手机必须重启。
233333
2024/07/02
2700
Android Binder机制(超级详尽)
binder通信是一种client-server的通信结构, 1.从表面上来看,是client通过获得一个server的代理接口,对server进行直接调用; 2.实际上,代理接口中定义的方法与server中定义的方法是一一对应的; 3.client调用某个代理接口中的方法时,代理接口的方法会将client传递的参数打包成为Parcel对象; 4.代理接口将该Parcel发送给内核中的binder driver. 5.server会读取binder driver中的请求数据,如果是发送给自己的,解包Parcel对象,处理并将结果返回; 6.整个的调用过程是一个同步过程,在server处理的时候,client会block住。
全栈程序员站长
2022/07/23
4.1K0
Android Binder机制(超级详尽)
Android系统服务(一)解析ActivityManagerService(AMS)
相关文章 Android系统启动流程系列 Android应用进程系列 Android深入四大组件系列 前言 1.概述 AMS是系统的引导服务,应用进程的启动、切换和调度、四大组件的启动和管理都需要AMS的支持。从这里可以看出AMS的功能会十分的繁多,当然它并不是一个类承担这个重责,它有一些关联类,这在文章后面会讲到。AMS的涉及的知识点非常多,这篇文章主要会讲解AMS的以下几个知识点: AMS的启动流程。 AMS与进程启动。 AMS家族。 2.AMS的启动流程 AMS的启动是在SyetemServer进程
用户1269200
2018/02/01
2K0
Android系统服务(一)解析ActivityManagerService(AMS)
推荐阅读
相关推荐
Android开发之漫漫长途 IX——彻底掌握Binder
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验