美文网首页我爱编程
如何添加系统Service

如何添加系统Service

作者: CyrusChan | 来源:发表于2018-04-14 14:21 被阅读44次

    简介

    今天来谈谈Android系统service,大家都知道android系统是基于Linux的。只不过是对Linux做了些修改和再封装。在我们android开发当中,各项system service的使用可谓是占了相当大的比例,较为经典的有为4大组件服务的ams、pms、zygote等。了解binder通信以及各种service的功能,对于我们理解android framework有很大帮助。关于binder通信相关的资料,网上可谓是汗牛充栋,大家最好了解下c++,嵌入式编程、linux编程,了解完这个。再去学习会事半功倍,推荐大家看一下韦东山老师的关于Binder通信的视频,讲解的比较详细(非拖)

    我们可以在手机shell中,用ps命令查看下运行进程[图片上传中...(image-33c17f-1523686626159-0)]

    我这用的是华为荣耀3的机器,看的出来里面的进程比较多,不清楚他们在做系统裁剪的时候做了什么。

    在这里我们可以看到zygote进程,这个进程是用来创建android应用进程的,每当我们启动activity和service或者其他组件的时候,一般都会检查这个组件。关于zygote的详细内容可以参考这篇文章以及AMS文章,内容较长但绝对干货。比我写的有价值多了。

    我们用命令ps之后,并没有发现与ams、pms的相关进程,这是因为这些服务都是一个叫system_server的进程拉起来的。和它隶属于同一个进程,在我们通过conext.getSystemService()方法拿到这些service的代理类,然后通过Binder与其进行通信。

    下面我们说说将服务做成SYSTEM SERVICE的一些好处:

    1.因为system_server进程会专门被监控,挂掉的时候会导致zygote自杀,然后系统重启。只要自己添加的service是稳定的,那么这个进程就会一直存在,我们就不用担心服务被干掉之类的。

    2.system_server属于system用户,权限略小于root,大于普通用户。这样我们自添加的service拥有较大的权限做一些特殊的事情。

    3.android framework启动过程中,service的启动是相当耗时的,因为有扫描应用程序的过程。而有些东西,我们需要在系统启动的时候做,例如启动的时候闪灯。这时候,我们就需要把一些操作放到Linux内核启动的过程中或者android环境启动过程中。Linux内核启动相对较快,综合考虑的话,还是放到android环境启动过程中较好。

    坏处就是system service编写和使用都比较麻烦,好在系统为我们提供了利用aidl添加service。下面我们来看看怎么添加service。

    一、编写IHelloWorld.aidl,并放到源码frameworks/base/core/java/android/os/ 下面(如果是在ide中写这些代码,注意写完之后编译下项目,否则无法生成相关的stub)

    // IHelloWorld.aidl.aidl
    package android.os;
    
    // Declare any non-default types here with import statements
    
    interface IHelloWorld {
        /**
         * Demonstrates some basic types that you can use as parameters
         * and return values in AIDL.
         */
         void printSth(String content);
         String getHelloWorld();
    
    }
    

    二、创建Service文件(java),放到源码 frameworks/base/services/core/java/com/android/server/下面

    package com.android.server;
    
    import android.os.IHelloWorld;
    import android.os.RemoteException;
    import android.util.Log;
    
    /**
     * Created by 41264 on 07/10/17.
     */
    
    public class HelloWorldService extends IHelloWorld.Stub {
    
        private static final String TAG = HelloWorldService.class.getSimpleName();
    
        @Override
        public void printSth(String content) throws RemoteException {
            Log.i(TAG, content);
        }
    
        @Override
        public String getHelloWorld() throws RemoteException {
            return "hello world";
        }
    }
    
    

    三、将自定义Service加入到SystemServer启动进程,先在 frameworks/base/core/java/android/content/Context.java 中添加一行

    public static final String HELLOWORLD_SERVICE="helloworld ";
    
    

    修改 frameworks/base/services/java/com/android/server/SystemServer.java

    在 startOtherServices() 函数 的try模块中增加以下代码

    try {
    
        Slog.i(TAG, "helloworld Service");
    
        ServiceManager.addService(Context. HELLOWORLD_SERVICE, new HelloWorldService());
    
    } catch (Throwable e) {
    
        Slog.e(TAG, "Failure starting helloworld Service ", e);
    
    }
    

    四、创建Manager,即HelloWorldManager,并放到frameworks/base/core/java/android/app/ 下

    package android.app;
    
    import android.content.Context;
    import android.os.IHelloWorld;
    import android.os.RemoteException;
    
    /**
     * Created by 41264 on 07/10/17.
     */
    
    public class HelloWorldManager {
        IHelloWorld mService;
        public HelloWorldManager(Context ctx,IHelloWorld service){
            mService = service;
        }
    
        public void printSth(String content){
            try {
                mService.printSth(content);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
    
        }
    
        public String getHelloWorld(){
            try {
                mService.getHelloWorld();
            } catch (RemoteException e) {
                e.printStackTrace();
            }
            return null;
        }
    }
    

    五、注册到SystemService,修改frameworks/base/core/java/android/app/SystemServiceRegistry.java,在静态代码块中增加如下代码

    registerService(Context. HELLOWORLD_SERVICE, HelloWorldManager.class,
            new CachedServiceFetcher() {
                @Override
                public HelloWorldManager createService(ContextImpl ctx) {
                    IBinder b = ServiceManager.getService(Context. HELLOWORLD_SERVICE);
                    IHelloWorld service = IHelloWorld.Stub.asInterface(b);
                    return new HelloWorldManager (ctx, service);
                }});
    

    六、编译

    make update-api 后再重新编译烧录系统(也可编译相应模块Push到系统中去)。

    七、测试

    有两种方式,一种是将编出来的jar包通过lib方式导入工程。jar包位置:out\target\common\obj\JAVA_LIBRARIES\framework_intermediates\classes.jar。另一种是在自建的app包下创建 HelloWorldManager类,导出Jar包供我们项目依赖。这样开发过程中就不会报错

    代码位置

    相关文章

      网友评论

        本文标题:如何添加系统Service

        本文链接:https://www.haomeiwen.com/subject/yillkftx.html