Android系统篇之—-编写系统服务并且将其编译到系统源码中【转】

本文转载自:http://www.wjdiankong.cn/android%E7%B3%BB%E7%BB%9F%E7%AF%87%E4%B9%8B-%E7%BC%96%E5%86%99%E7%B3%BB%E7%BB%9F%E6%9C%8D%E5%8A%A1%E5%B9%B6%E4%B8%94%E5%B0%86%E5%85%B6%E7%BC%96%E8%AF%91%E5%88%B0%E7%B3%BB%E7%BB%9F%E6%BA%90%E7%A0%81/

在之前已经介绍了一篇关于 如何编写简单的驱动以及访问该驱动的小程序,最后将程序编译到Android内核源码中通过程序访问驱动验证是可以通过的,那么本文就继续这个知识点,把这个驱动程序通过JNI连接创建一个系统服务,提供给上层应用访问改服务功能,可以看到前一篇介绍驱动程序的功能是属于内核层的,而本文介绍的内容是Framework层的知识。

声明:本文内容参考罗升阳的书籍:《Android系统源代码情景分析》 如果想了解更详细的内容非常建议购买此书

非常感谢罗神的这本书,给我带来很多未知的知识,大神的博客地址:http://blog.csdn.net/luoshengyang

一、编写JNI层服务代码

第一步:创建JNI目录

进入到系统的JNI目录中:frameworks/base/services/jni 在这个目录中包含了系统服务的所有JNI实现的程序:

第二步:编写JNI代码

实现代码也比较简单,直接访问之前编译好的驱动即可,然后在提供给外部一个读写的方法,最后在进行JNI方法的手动注册:

第三步:修改编译脚本

在同一目录中有一个Android.mk文件,需要添加我们的这个服务,后续要将这个服务编译到源码中:

第四步:添加服务JNI功能的加载配置

上面已经编写好了我们的系统服务功能,也手动注册了一些读写方法,那么还需要把这个注册功能添加到系统的onload.cpp文件中被调用,不然系统编译之后也是找不到那个JNI方法的,而这个onload.cpp程序,是系统启动的时候去运行,内部是专门注册系统服务的JNI方法的:

第五步:编译framework层源码

上面几步已经完成了代码编写和脚本配置,下面就可以直接编译源码,把这个服务的JNI功能编译到源码中,可以直接使用mmm命令进行单独模块的编译:

mmm frameworks/base/services/jni
make snod

这样编译之后的system.img中就包含了我们定义的系统JNI服务实现逻辑,接下来我们就可以编写Java代码来访问这个JNI暴露的读写方法了。

二、编写Java层服务代码

第一步:创建服务的AIDL文件

进入系统服务的AIDL文件目录:frameworks/base/core/java/android/os 这里存放了系统所有服务的AIDL定义

关于AIDL内容,也是很简单的,提供读写方法:

第二步:编译AIDL文件

我们在使用AIDL的时候都知道,定义完文件之后,必须编译一下,生成对应的Java代码,这样后续才能使用类似于XXX.Stub类,才能在远端服务实现具体功能。这里也是一样的,所以我们得先编译这个aidl文件:

mmm frameworks/base

单独编译framework模块代码,这样就会产生对应的IFregService.Stub类了。

第三步:实现具体服务功能

上面已经编译aidl文件,生成了对应的java代码,下面如果想实现具体的功能,就必须继承Stub类,这个文件存放的目录为:frameworks/base/services/java/com/android/server 系统中所有具体服务实现都是在这个目录中:

代码实现也比较简单:

在这里会定义读写的native方法,和之前的JNI层实现的方法对应:

第四步:将服务添加到ServiceManager中

为了让上次访问到这个服务,和系统其它服务一样,咋们必须得把服务注册到ServiceManager中,而这个注册功能是在SystemServer类中,因为在系统启动的时候,Zygote进程产生的第一个进程就是system_server,在这个进程中做了系统服务的注册工作,我们在服务的同一目录中找到SystemServer.java类,在ServerThread::run函数中注册:

这样注册之后,上层应用就可以通过ServiceManager直接获取到这个服务了,就可以直接访问具体功能了。

第六步:编译Framework源码

上面都已经完成了Java层服务代码的实现了,而到这里,我们似乎已经看到了熟悉的代码了,比如服务的AIDL定义,实现和注册服务功能,和之前介绍的 Binder机制以及远程服务调用机制的知识 越来越接近了,下面在最后一步,编译源码:

mmm frameworks/base/services/java
make snod

编译之后得到system.img文件就包含了我们在Framework定义的FregService服务了,而这个服务的名称是freg,下面继续介绍如何编写一个程序来访问这个服务功能。

三、编写系统应用访问服务功能

前面已经介绍了编写Framework中的服务功能,在JNI层实现了访问驱动的native代码,然后实现了Java层代码调用这些native方法实现驱动的读写功能,并且定义了一个系统服务,包装这些功能,最后把这个服务注册到系统中,这里我们就来编写一个简单的Android系统程序,来访问这个服务功能:

第一步:创建程序项目

创建系统程序项目都是在这个目录中:packages/experimental,我们定义一个Freg项目:

这个项目结构和正常的Android程序结构一样,没什么好说的,因为这里不是依赖于IDE编译,所以咋们还得编写编译脚本Android.mk文件:

关于Android程序代码也比较简单,直接通过ServiceManager来访问这个服务即可:

第二步:编译应用程序

上面的程序创建完成之后,接下来再次编译源码,把这个应用打包到系统中:

mmm packages/experimental/Freg
make snod

编译完成之后,生成的system.img文件就包含了这个系统应用程序

第三步:启动模拟器验证程序

接下来咋们就可以启动模拟器,来运行这个小程序了:

emulator -kernel kernel/common/arch/arm/boot/zImage &

我们找到这个程序之后,打开的效果:

打开这个程序之后,我们可以进行读写操作了:

四、流程总结

到这里我们就成功了完成了手动编写一个简单的系统服务并且添加到系统中,结合之前的一篇文章内容,下面就来总结整个过程,先来一张图压压惊:

有了这张图咋们再来总结一下:

1、编写驱动
1>在 kernel/driver 目录下创建freg驱动程序
2>make menuconfig 编译驱动程序到内核源码中

2、编写Framework层服务的JNI程序
1>在 frameworks/base/services/jni 目录下创建了服务的jni代码
2>在onload.cpp中添加服务jni方法的注册逻辑
3>mmm frameworks/base/services/jni 编译jni程序到系统源码中

3、编写Framework层服务的Java程序
1>在 frameworks/base/core/java/android/os 目录下创建了服务的AIDL文件
2>mmm frameworks/base 编译AIDL文件,生成对应的Java代码
3>在 frameworks/base/services/java/com/android/server 目录中编写具体服务的实现功能
4>最后在同一目录下找到SystemServer.java文件中注册该服务(ServiceManager.addService方法)
5>mmm frameworks/base/services/java 编译java层服务

4、编写系统Android应用程序
1>在 packages/experimental 目录下创建Android项目,在程序中直接使用ServiceManager来得到远端服务即可
2>mmm packages/experimental/Freg 编译程序到系统中
3>启动模拟器验证结果 :emulator -kernel kernel/common/arch/arm/boot/zImage &

说到底,其实这个实验有的同学可能非常感兴趣,可能想立马就实验一把,但是这里现在最大的问题就是你得必须先编译过Android源码,这个是最核心的也是最基本的,然后在按照这些流程走的话就很简单了,所以作为一个Android开发者毕生还是要编译一次Android源码的。所以感兴趣的同学应该赶快动起手来编译Android源码。

项目地址下载:http://download.csdn.net/detail/jiangwei0910410003/9642835

五、总结

到这里就结束了如何手动编写系统服务并且添加到系统中的工作了,同时也暂时结束了这段时间介绍的Android系统篇的系列知识,其实我本来只是想介绍如何Hook掉系统的AMS服务拦截应用启动的知识,可是谁都想不到引出了这么一大串的知识出来,没办法我也只能慢慢的一篇一篇介绍了。

时间: 2024-08-06 14:48:47

Android系统篇之—-编写系统服务并且将其编译到系统源码中【转】的相关文章

Android系统篇之----编写系统服务并且将其编译到系统源码中

在之前已经介绍了一篇关于如何编写简单的驱动以及访问该驱动的小程序,最后将程序编译到Android内核源码中通过程序访问驱动验证是可以通过的,那么本文就继续这个知识点,把这个驱动程序通过JNI连接创建一个系统服务,提供给上层应用访问改服务功能,可以看到前一篇介绍驱动程序的功能是属于内核层的,而本文介绍的内容是Framework层的知识. 声明:本文内容参考罗升阳的书籍:<Android系统源代码情景分析> 如果想了解更详细的内容非常建议购买此书 非常感谢罗神的这本书,给我带来很多未知的知识,大神

Android系统篇之—-编写简单的驱动程序并且将其编译到内核源码中【转】

本文转载自:大神 通过之前的一篇文章,我们了解了 Android中的Binder机制和远程服务调用 在这篇文章中主要介绍了Android中的应用在调用一些系统服务的时候的原理,那么接下来就继续来介绍一下如何通过编译Android源码来手动添加一个系统服务,让编译之后的Android系统中存在我们的这个服务,每个应用都可以调用.但是本文得先介绍一下如何编写一个简单的驱动程序,先介绍了驱动程序,然后在通过JNI让framework层访问这个驱动程序,在通过注册服务来封装这个功能,最后在把这个服务添加

Android系统篇之----编写简单的驱动程序并且将其编译到内核源码中

通过之前的一篇文章,我们了解了 Android中的Binder机制和远程服务调用 在这篇文章中主要介绍了Android中的应用在调用一些系统服务的时候的原理,那么接下来就继续来介绍一下如何通过编译Android源码来手动添加一个系统服务,让编译之后的Android系统中存在我们的这个服务,每个应用都可以调用.但是本文得先介绍一下如何编写一个简单的驱动程序,先介绍了驱动程序,然后在通过JNI让framework层访问这个驱动程序,在通过注册服务来封装这个功能,最后在把这个服务添加到系统中,实现上层

访何红辉:谈谈Android源码中的设计模式

最近Android 6.0版本的源代码开放下载,刚好分析Android源码的技术书籍<Android源码设计模式解析与实战>上市,我们邀请到它的作者何红辉,来谈谈Android源码中的设计模式,以及近期Android开发中的一些热点话题. 受访嘉宾介绍: 何红辉(@MrSimp1e),前友盟Android工程师,活跃于国内各大技术社区,热爱开源,热爱技术,热爱分享.Android开源库 AndroidEventBus . Colorful 作者, 开发技术前线 站长,<Android源码

使用Xamarin开发手机聊天程序 -- 基础篇(大量图文讲解 step by step,附源码下载)

如果是.NET开发人员,想学习手机应用开发(Android和iOS),Xamarin 无疑是最好的选择,编写一次,即可发布到Android和iOS平台,真是利器中的利器啊!而且,Xamarin已经被微软收购并被大力推广,.NET开发人员将时间投资在Xamarin上,以应对移动开发的热潮,应该是值得的. 好了,废话不多说,就开始吧.本系列文章将详细介绍如何使用Xamarin开发出一个简单的即时通信IM聊天系统(文末有源码下载,可先睹为快),本文作为第一篇基础篇,将着重介绍Xamarin Andro

Android 源码中的设计模式

最近看了一些android的源码,发现设计模式无处不在啊!感觉有点乱,于是决定要把设计模式好好梳理一下,于是有了这篇文章. 面向对象的六大原则 单一职责原则 所谓职责是指类变化的原因.如果一个类有多于一个的动机被改变,那么这个类就具有多于一个的职责.而单一职责原则就是指一个类或者模块应该有且只有一个改变的原因.通俗的说,即一个类只负责一项职责,将一组相关性很高的函数.数据封装到一个类中. 开闭原则 对于扩展是开放的,这意味着模块的行为是可以扩展的.当应用的需求改变时,我们可以对模块进行扩展,使其

从源码中浅析Android中如何利用attrs和styles定义控件

一直有个问题就是,Android中是如何通过布局文件,就能实现控件效果的不同呢?比如在布局文件中,我设置了一个TextView,给它设置了textColor,它就能够改变这个TextView的文本的颜色.这是如何做到的呢?我们分3个部分来看这个问题1.attrs.xml  2.styles.xml  3.看组件的源码. 1.attrs.xml: 我们知道Android的源码中有attrs.xml这个文件,这个文件实际上定义了所有的控件的属性,就是我们在布局文件中设置的各类属性 你可以找到attr

android四大组件之Activity - (1)从源码中理解并巧用onWindowFocusChanged(boolean hasFocus)

这里开始到后面,想趁着有时间,将Android四大组件和一些系统组件做一些总结和记录.由于网上已经有很多写的很好并且总结也全面的文章.小弟我也囊中羞涩不敢献丑,就记录一些自己觉得重要的有用的知识点,顺便大家一起学习讨论啥的也好 Activity作为四大组件之一,对于整个Android开发有多重要就无需赘言了.关于它的生命周期,这里借用下官网的图,便一目了然: 那么它的生命周期和我们所说的onWindowFocusChanged(boolean hasFocus)方法有何关系? Activity生

为什么android源码中有的public方法,在官网会查不到并且我们也用不了?

比如,看这个: 在android开发官网上搜是搜不到这个方法的,我们也调用不了,为什么呢?这是因为我们只能调用到android Framework层给我们提供的api,而这个方法框架层不开放调用,所以自然我们就调用不到了.不过,我们可以通过反射的方式间接调用此类方法(详细见我上一篇博客). 附在线看android源代码网址:http://grepcode.com/project/repository.grepcode.com/java/ext/com.google.android/android