在之前已经介绍了一篇关于如何 编写简单的驱动以及访问该驱动的小程序,最后将程序编译到Android内核源码中通过程序访问驱动验证是可以通过的,那么本文就继续这个知识点,把这个驱动程序通过JNI连接创建一个系统服务,提供给上层应用访问改服务功能,可以看到前一篇介绍驱动程序的功能是属于内核层的,而本文介绍的内容是Framework层的知识。
声明:本文内容参考罗升阳的书籍:《Android系统源代码情景分析》 如果想了解更详细的内容非常建议购买此书,非常感谢罗神的这本书,给我带来很多未知的知识,大神的博客地址:
http://blog.csdn.net/luoshengyang
温馨提示:昨天网站挂了,抢修了一下,今天恢复了,谢谢热心用户反馈问题:http://www.wjdiankong.cn
一、编写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服务拦截应用启动的知识,可是谁都想不到引出了这么一大串的知识出来,没办法我也只能慢慢的一篇一篇介绍了。
手机看文章有点费劲,可以进入网页版:http://www.wjdiankong.cn
关注微信公众号:编码美丽 (微信号:jiangwei0910410003)
推荐阅读:旗龙网
-
麦咭小小编程师教你做《万有引力》小游戏--福
由深圳市科学技术协会、福田区科技创新局(福田区科协)指导,由福田区华富办事处妇女联合会、深圳市新联会科技联盟、深业上城联合体综合党委、深圳市高科技企业协同创新促...
2021-05-08 -
加拿大留学移民必备电话卡,双十一“神秘计划”
加拿大气候虽然慢慢变冷了但双十一以及黑五的临近又点燃了大家的购物热情每到一年秋冬季节,只有买买买能让体温升高各种优惠折扣看得眼花缭乱来!让小编教你~怎么在双十一...
2020-11-11 -
留学省钱攻略之加拿大电话卡|文末有福利彩蛋
加拿大的电话套餐是出了名的贵。作为非土豪留学生一枚,平时适当省检是留学生活的基本方针。毕竟谁的钱也不是大风刮来的。所以就电话卡的挑选简单分享一下省钱攻略:我之前...
2020-10-26 -
南方医科大学以学分制改革打通成人教育和自学考
建16个成人教育校外授课点和23个自考互助点南方医科大学以学分制改革打通成人教育和自学考试校本部正门媒体记者了解到,南方医科大学继续教育学院前身为第一军医大学继...
2020-07-24 -
有才又有料!第六届上汽通用汽车校园创新传播工
近日,第六届上汽通用汽车校园创新传播工场(ICCG)在广大高校师生的期待中盛势启幕,年度大学生跨界创意盛宴正式上线。作为面向大学生推出的校园创新平台,第六届IC...
2020-06-15 -
沈梦辰晒日系旅游美照 白T恤配米色阔腿裤减龄
9月4日,沈梦辰在微博晒出一组旅行美照并配文:“结果不重要,过程才是风景。”照片中,沈梦辰身穿白色T恤搭配米色阔腿裤,十分清新。沈梦辰美照沈梦辰...
2019-09-05 -
让地球氧气在5亿年前猛增的神秘力量找到了
宇宙探秘本报记者 张 晔氧气是人类和动物赖以生存的基础。但是,远古时期的地球曾极度缺氧,是一片不折不扣的生命禁区。然而,到了距今5.8亿—5.2亿年左右,地球氧...
2019-09-05 -
猪肉价格涨疯了 卖车还不如养猪挣钱?
最近,猪肉价格上涨引起广泛关注,据搜猪网分析师冯永辉测算,按照目前生猪市场价格,养殖户头均盈利已达到1491元,创历史新高。对此,有网友调侃,“猪”似乎有成为“...
2019-09-05