前言
上一篇《定制ROM采坑之路(2):魔趣OS刷入小米5A手机过程详解》我们已经知道了怎么将魔趣刷入到我们的手机中了。接下来,这篇文章我想通过开发一个入门级别的系统级App把我们的流程走通,对系统级的App有个最初步的认识,本文章没有涉及到一些高级的功能比如调用系统级API
、引用本地库
。在文章结尾会有一篇推荐文章,会比我这篇文章的内容多一点大家可以点击观看。
系统级App的开发
参考用例——HelloActivity
今天我们开发的第一个系统级应用,主要的参考例子就是源码树中给的例子:[your android source path]/development/samples
中的HelloActivity
。
以此项目为基础,构建我们的第一个系统级App。我通过Ftp把源码下载下来使用sublime3打开,下面来张截图看下源码。
可以看见源码很简单,接下来就是修改我们的Android.mk文件
。
创建Android.mk文件
- 首先,我们将HelloActivity项目拷贝到我们的
/packages/apps目录
下,并更名为FirstSystemApp。
$ sudo cp -r HelloActivity /var/android/rom/mokee/source/packages/apps/HelloActivity
$ cd /var/android/rom/mokee/source/packages/apps/
$ mv HelloActivity FirstSystemApp
- 其次,通过对复制HelloActivity的Android.mk文件内容为模版修改为下面的内容。
LOCAL_PATH:= $(call my-dir)
#清理缓存变量
include $(CLEAR_VARS)
#表示目标模式
LOCAL_MODULE_TAGS := userdebug
#表示源文件编译路径 这个应用里面只有java源文件
LOCAL_SRC_FILES := $(call all-java-files-under, src)
#表示项目包名也就是模块名,在项目中唯一
LOCAL_PACKAGE_NAME := FirstSystemApp
#签署当前应用的证书名称
LOCAL_CERTIFICATE := platform
#指定编译sdk版本为当前版本
LOCAL_SDK_VERSION := current
# 使用该指令编译目标Apk.
include $(BUILD_PACKAGE)
#搜索编译该源码目录下所有的mk文件,如果没有可以不写
include $(call all-makefiles-under,$(LOCAL_PATH))
上面大部分都是通用写法,但是有几个变量定义我们需要这种了解一下
-
LOCAL_PACKAGE_NAME
该变量的值是FirstSystemApp
,所以会在<Android 源代码根目录>//out/target/product/[your product]/system/app/
目录生成FirstSystemApp.apk文件。 -
LOCAL_CERTIFICATE
Android系统中包含了4个签名,前面使用的platform就是其中之一。这些签名文件中在如下的目录中。
<Android 源代码根目录>/build/target/product/security
下面解释一下含义:
- testkey:适用于未另外指定密钥的 apk 包的通用默认密钥。
- platform:适用于核心平台所包含的 apk 包的测试密钥。
- shared:适用于家庭/联系人进程中的共享内容的测试密钥。
- media:适用于媒体/下载系统所包含的 apk 包的测试密钥。
此变量表示签名类型,系统应用通常设为platform,表示Platform签名。具体参考《证书和私钥》
- LOCAL_MODULE_TAGS
在针对特定产品进行编译时,如果能在最终发布版本的基础上进行细微修改,通常会非常有用。在模块定义中,模块可以通过 LOCAL_MODULE_TAGS 指定标记,这些标记可以是以下一个或多个值:optional(默认)、debug、eng。更多可以参考官网的文章《使用编译类型》
配置Makefile,添加新的项目
注意,这是很关键的一步,如果忽略了你是没办法在编译成的system.img里面找到这个工程的。
这一步,我们需要将我们刚才创建的FirstSystemApp
添加到系统的mk文件下,编译后会产生一个FirstSystemApp
项目。
选择 <Android 源代码根目录>/device/xiaomi/rolex/device.mk
或者从 build/target/product/
目录下选择一个被引用的.mk
文件,比如我用的是build/target/product/core.mk
,如果是在/devices/下指定产品下修改添加,则只会在指定目标产品生效,如果你的工程对所有产品有效,建议添加在/build/target/product/core.mk中。
最重要的是在其中的PRODUCT_PACKAGES参数列表中添加本工程:如果不添加的话整编出来的镜像里面是没有添加到源码树的应用的。下面要提到的添加公用so文件也是需要在这个地方添加,添加的方式则是把mk文件中的标识名填上(LOCAL_PACKAGE_NAME或者LOCAL_MODULE)。
编译
在FirstSystemApp目录下输入mm命令或者切换到Android源码根目录下执行下面任意一条命令即可:
make FirstSystemApp
或者mmm package/apps/FirstSystemApp
耐心等待十几分钟等编译,编译生成的apk会放到在<Android 源代码根目录>/out/target/product/[your product]/system/app/
目录下。
安装
因为我编译是在服务器上进行的,所以需要将APK下载到本地后,安装到手机上。系统级app的安装和普通的应用安装不同,在有root的情况下,我们只需要将Apk使用adb命令push到手机的/system/app
下就好了执行命令。
$ adb remount
$ adb push FirstSystemApp.apk /system/app
$ adb shell
$ cd /system/app
$ ls
下面图可以看见,确实已经是系统级的App了,因为只可以停用
但不可以卸载。
结束语
总的来说系统级应用的入门开发并不难,出去掉图片和命令,并没有多少内容。这篇文章还有很多都没有涉及比如:jar包的引用
、so库的引用
、makefile细节编写
、调用系统隐藏API
等否没有涉及。这里我推荐一篇文章《android系统源码中添加app源码(源码部署移植)》,因为本文也是通过这篇文章的编写出来的基础篇,他的文章要更全面一点。