Android Framework学习(一)系统服务相关

Android Framework:
- Android Framework学习(一)系统服务相关
- Android Framework学习(二)应用进程启动相关
- Android Framework学习(三)Activity相关

Android Framework涉及到linux相关,本文也只是冰山一角,但是虽不能窥其全貌,了解其具体流程还是有点必要的。

Zygote启动

我们知道Android的所有进程都是通过Zygote进程孵化而来的,那就有个疑问Zygote又是哪来的?
所有,我们首先来了解一下Zygote进程是怎么启动的。
首先Linux系统启动后会在用户空间创建第一个进程init进程,进程号固定为1。然后调用init中的main()方法执行init进程的职责。对于init进程的功能分为4部分:

  • 解析并运行所有的init.rc相关文件
  • 根据rc文件,生成相应的设备驱动节点
  • 处理子进程的终止(signal方式)
  • 提供属性服务的功能

在这里便通过fork和execve系统调用启动了Zygote进程.
在这里插入图片描述
Zygote启动之后,会先进入native层。启动Android的虚拟机–>注册Android的JNI函数–>再进入Java层。
来到java层后。主要是做一下事情

  • 预加载资源:便于后面孵化子进程时能够方便继承,预加载通用类、drawable和color资源、openGL以及共享库以及WebView,用于提高app启动效率
  • System_server:也就是系统服务了,要注意这一点,是由zygote进程fork而来的。
  • Socket Loop循坏:用来处理socket通信相关的,当接收到请求创建新进程请求时立即唤醒并执行相应工作。
    在这里插入图片描述
    这里要注意一个问题:
    Zygote进程fork子进程的需要单线程环境,因为fork的时候会继承父进程的资源,如果父进程时多线程环境的话,容易出现死锁及线程间同步问题,所有fork时会切换到单线程环境。
    同时这也解决了一个疑问,Zygote的IPC为什么没有采用Binder机制,按道理说Binder机制很明显要优于Socket通信,但是也就是因为Binder通信是多线程环境这个原因,故而采用了socket。

系统服务启动

下面来具体深入到代码来看SystemServer是如何启动的。
这里只截取部分,不追究细节,不然看的云里雾里毫无头绪。注意在SDK28中变为了forkSystemServer方法
ZygoteInit.java

//准备参数用于启动SystemServer
private static Runnable forkSystemServer(String abiList, String socketName,
            ZygoteServer zygoteServer) {
         ...
		/* Hardcoded command line to start the system server */
        String args[] = {
            ...
            "com.android.server.SystemServer",
        };
        ZygoteConnection.Arguments parsedArgs = null;

        int pid;

        try {
            parsedArgs = new ZygoteConnection.Arguments(args);
            ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
            ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);

            boolean profileSystemServer = SystemProperties.getBoolean(
                    "dalvik.vm.profilesystemserver", false);
            if (profileSystemServer) {
                parsedArgs.runtimeFlags |= Zygote.PROFILE_SYSTEM_SERVER;
            }

            /* Request to fork the system server process */
            //请求创建SystemServer进程
            pid = Zygote.forkSystemServer(
                    parsedArgs.uid, parsedArgs.gid,
                    parsedArgs.gids,
                    parsedArgs.runtimeFlags,
                    null,
                    parsedArgs.permittedCapabilities,
                    parsedArgs.effectiveCapabilities);
        } catch (IllegalArgumentException ex) {
            throw new RuntimeException(ex);
        }

        /* For child process */
        if (pid == 0) {
        	//执行SystemServer进程内方法解析启动参数
            if (hasSecondZygote(abiList)) {
                waitForSecondaryZygote(socketName);
            }

            zygoteServer.closeServerSocket();
            //完成剩余的启动工作
            return handleSystemServerProcess(parsedArgs);
        }

        return null;

下面来看SystemServer启动
SystemServer.java

public static void main(String[] args) {
        new SystemServer().run();
    }

private void run() {
		//创建消息循坏
        Looper.prepareMainLooper();

        // Initialize native services.
        System.loadLibrary("android_servers");

        // Initialize the system context.
        createSystemContext();

        // Start services.
        try {
            traceBeginAndSlog("StartServices");
            //可见系统服务分为以下三类
            startBootstrapServices();// 启动引导服务
        	startCoreServices();      // 启动核心服务
        	startOtherServices();     // 启动其他服务
            SystemServerInitThreadPool.shutdown();
        } 
        // Loop forever.
        Looper.loop();
        throw new RuntimeException("Main thread loop unexpectedly exited");
    }

SystemServer有很多,那它的启动流程是什么样的?
其主线也是按照上面的启动顺序,先启动引导服务:AMS、PMS等;再启动核心服务BatteryService、UsageStatsService、WebViewUpdateService等;最好启动其他的非必需服务:闹钟服务什么的啊
具体流程可参考Gityuna大神的文章Android系统启动-SystemServer下篇
在这里插入图片描述
好了,了解了系统服务的启动后,首先肯定最先看到的是桌面应用,所有来看下桌面的启动。
桌面的启动是再AMS启动后开始启动的,能再AMS中的systemReady()方法中看到调用了startHomeActivityLocked()方法
ActivityManagerService.java

boolean startHomeActivityLocked(int userId, String reason) {
        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
                && mTopAction == null) {
            // We are running in factory test mode, but unable to find
            // the factory test app, so just sit around displaying the
            // error message and don't try to start anything.
            return false;
        }
        //这里是获取Home的MainActivity的Categary
        Intent intent = getHomeIntent();
        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
        if (aInfo != null) {
        //下面是获取启动所需的参数,比如桌面上需要显示的App信息
            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
            // Don't do this if the home app is currently being
            // instrumented.
            aInfo = new ActivityInfo(aInfo);
            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
                    aInfo.applicationInfo.uid, true);
            if (app == null || app.instr == null) {
                intent.setFlags(intent.getFlags() | FLAG_ACTIVITY_NEW_TASK);
                final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
                // For ANR debugging to verify if the user activity is the one that actually
                // launched.
                final String myReason = reason + ":" + userId + ":" + resolvedUserId;
                //这里启动Home的Activity
                mActivityStartController.startHomeActivity(intent, aInfo, myReason);
            }
        } else {
            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
        }

        return true;
    }

添加自定义系统服务

我们知道,当客户端想要访问系统服务时,会通过ServerManager来查找系统服务,如果找到则返回对应的Binder,然后客户端可通过该Binder与Servive建立通信。总体的过程如下:
在这里插入图片描述
再来要了解系统服务的使用流程,首先通过context的getSystemService方法获取系统服务,Context的实现类为ContextImpl
ContextImpl.java

    @Override
    public Object getSystemService(String name) {
        return SystemServiceRegistry.getSystemService(this, name);
    }

SystemServiceRegistry.java

private static final HashMap<String, ServiceFetcher<?>> SYSTEM_SERVICE_FETCHERS =
            new HashMap<String, ServiceFetcher<?>>();

    public static Object getSystemService(ContextImpl ctx, String name) {
        ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name);
        return fetcher != null ? fetcher.getService(ctx) : null;//getService主要是从Context获取服务,如果未获取到则创建
    }

先以BatterService为例,
BatteryStatsService.java

    public static IBatteryStats getService() {
        if (sService != null) {
            return sService;
        }
        //这里也就是获取到对应的IBinder对象
        IBinder b = ServiceManager.getService(BatteryStats.SERVICE_NAME);
        sService = asInterface(b);
        return sService;
    }

这里类似于AIDL一样,ServiceManager里面都是空实现,具体的AIDL绑定在ServiceManagerNative中
ServiceManagerNative.java

class ServiceManagerProxy implements IServiceManager {
	//只截取部分
    public ServiceManagerProxy(IBinder remote) {
        mRemote = remote;
    }

    public IBinder asBinder() {
        return mRemote;
    }

//熟悉的AIDL自动生成的方法,返回对应的IBinder
    public IBinder getService(String name) throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IServiceManager.descriptor);
        data.writeString(name);
        mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);
        IBinder binder = reply.readStrongBinder();
        reply.recycle();
        data.recycle();
        return binder;
    }

这也也就从ServerManager中获取到了系统服务。具体的添加服务也同上面一样,使用addService()方法,可能这里说的不是很深入,因为涉及到了native层,要深入的话需要大篇幅的描述,因此这里就只说明其功能。

系统服务与应用Binder服务的区别

系统服务的启动:在前面的SystemServer中也看到过,通过run方法来启动,来完成服务的初始化。也看的出是主动注册服务的。

        try {
            traceBeginAndSlog("StartServices");
            //可见系统服务分为以下三类
            startBootstrapServices();// 启动引导服务
        	startCoreServices();      // 启动核心服务
        	startOtherServices();     // 启动其他服务
            SystemServerInitThreadPool.shutdown();
        } 

系统服务的具体调用的过程则如下所示,
在这里插入图片描述
应用服务的启动:
通过startService–>ContextImpl中的startServiceCommon()方法中,服务间通信建立、管理、调度的过程是交给AMS。具体的创建还是需要交给应用端完成的,完成实例创建,生命周期回调等。
应用服务的调用过程:
在这里插入图片描述
应用服务则不是主动注册的,而是发起bindService请求后,由AMS自己去寻找服务请求binder。被动注册。

两者的使用方式上,我个人决定在大体上区别不大,都是属于Binder范畴中,
系统服务使用是通过ServiceManager直接获取到该服务的binder对象,利用了Binder连接池,然后再利用binder对象得到暴露的接口。
应用服务则是通过Service端传入的IBinder对象获取暴露的接口。

发布了38 篇原创文章 · 获赞 6 · 访问量 3400

猜你喜欢

转载自blog.csdn.net/qq_37704124/article/details/100314336