本节书摘来自异步社区《Android深度探索(卷2):系统应用源代码分析与ROM定制》一书中的第6章,第6.3节如何编写Android系统应用,作者 李宁,更多章节内容可以访问云栖社区“异步社区”公众号查看
6.3 如何编写Android系统应用Android深度探索(卷2):系统应用源代码分析与ROM定制源代码目录:src/ch06/FirstSystemApp
Android系统应用和普通的Android应用基本相同,都是主要用Java语言编写的APK程序。不过前者与后者有如下两点不同。
签名不同。Android系统应用使用的是系统签名,或称为平台(Platform)签名,而普通的Android应用使用的是一般的签名。可以访问的API不同。在Android SDK中有很多API(类、接口、方法等)都声明为hide1。这类API不允许在普通的Android应用中访问,而只有经过Platform签名的Android系统应用才能使用这些API。除了以上两点,Android系统应用和普通应用的创建过程基本相同,只是由于Android系统应用可能访问系统级的API(hide API),而ADT是不会识别这些API的,所以在ADT+Eclipse开发环境导入Android系统应用的源代码后会发现使用这些API的地方都用红色波浪线标注了。不过这不要紧,反正也不在IDE中编译和运行Android系统应用。
在了解了Android系统应用和普通的Android应用的区别后,面临的下一个问题就是如何编译和运行Android系统应用呢?
Android系统应用完全可以像普通的Android应用一样在Eclipse中编辑,IDE的基本特性仍然会保留,但由于使用了系统API,所以是不能直接编译的。要想编译Android系统应用,必须要依靠Android源代码(最好是已经进行一遍完整编译的Android源代码)才可以。通常会将Android系统应用的源代码放到/packages/apps目录或其子目录中。编译Android系统应用开需要在程序的根目录建立一个Android.mk文件,该文件是Android源代码专用的编译文件,相当于GCC的Makefile文件。至于该文件的内容,通常并不需要有更深入的了解,只需要在apps目录中找一个Android系统应用,如PackageInstaller,将该程序中Android.mk文件复制一份,然后进行适当修改即可。
本节提供了一个普通的Android应用(FirstSystemApp),该程序并未调用任何系统API,所以可以直接在Eclipse中编译和运行。不过只要加入了Android.mk文件,就可以将FirstSystemApp程序变成Android系统应用,并安装到Android设备的/system/app2目录中。下面先看一下FirstSystemApp程序的Android.mk文件的内容。
src/ch06/FirstSystemApp/Android.mk LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE_TAGS := optional LOCAL_SRC_FILES :=$(call all-java-files-under, src) LOCAL_STATIC_JAVA_LIBRARIES += android-support-v4 # 将编译生成FirstSystemApp.apk文件 LOCAL_PACKAGE_NAME := FirstSystemApp LOCAL_CERTIFICATE := platform include $(BUILD_PACKAGE)Android.mk文件的大多数内容都是标准的写法,只有下面两行代码需要了解一下。
LOCAL_PACKAGE_NAME := FirstSystemApp LOCAL_CERTIFICATE := platform其中第一行需要根据不同的Android系统应用进行修改。系统会根据LOCALPACKAGE NAME变量的值生成APK文件,例如,本例该变量的值是FirstSystemApp,所以会在out/target/product/ maguro/system/app目录生成FirstSystemApp.apk文件,如果Android设备已经获取了root权限,直接将该文件使用adb push命令上传到/system/app目录即可。如果Android设备没有root权限,就只能通过刷机的方式安装系统应用了。要注意的是FirstSystemApp.apk不能通过普通应用的方式进行安装。LOCAL_CERTIFICATE变量表示签名类型,系统应用通常设为platform,表示Platform签名。
在随书光盘中提供的Android源代码已经包含了本节的例子,读者需要在Linux终端进入如下的目录,并执行mm命令即可编译FirstSystemApp。
/packages/apps/ch06/FirstSystemApp如果当前的Linux终端为进行Android的初始化,需要在Android源代码本目录中执行如下的命令进行初始化,否则无法执行mm命令。
为了方便读者,在本书中实现的每一个Android系统应用根目录都带了一个update.sh脚本文件,只需要执行source update.sh命令,就会自动编译和上传当前的系统应用到Android设备的/system/app目录。
扩展学习:Android系统的签名Android源代码中包含了4个签名,前面使用的platform就是其中之一。这些签名文件中在如下的目录中。
/build/target/product/security下面解释一下这4个前面的含义。
testkey:普通的Key,默认情况下使用。如果Android.mk文件不设置LOCAL_CERTIFICATE 变量,就使用该签名。platform :使用该签名的系统应用可以执行平台的核心功能。shared :使用该签名的系统应用可以和home/contacts进程共享数据。media :使用该签名的系统应用将成为media/download 系统的一部分。LOCAL_CERTIFICATE 变量可以指定上述4个值,例如,如果值为platform,会使用security目录的platform.pk8文件对APK文件进行签名。如果值为media,会使用media.pk8文件对APK文件进行签名。
1由于Android SDK中某些API非常危险,例如,可以静默安装、卸载程序、拦截电话等,所以Google公司在设计这些API时将其声明为hide,以便只有在Android系统应用中才能使用。这些Android系统应用不能通过常规方法安装,只能在有root权限的情况下上传到Android设备的/system/app目录,或随ROM一起发布,还可以通过刷机(升级包)的方法安装这些应用。这就限制了这些危险API的使用,从而大大降低使用Android系统的风险。2要注意的是Android源代码中存储系统应用的目录是apps,而Android设置中存储二进制形式系统应用的目录是/system/app,它们差一个“s”,不要弄混了!
相关资源:Android深度探索(卷2)系统应用源代码分析与ROM定制.part4