给Android源码增加一个项目

来源:互联网 发布:软件企业即征即退 编辑:程序博客网 时间:2024/05/17 23:28

      所谓增加一个项目的意思是,增加一个子项目,以便于Android源码遍以后,编译目标中能够包含该项目。比如:可以增加一个C/C++工具程序,从而可以在目标系统的shell命令行下使用该工具。再比如,可增加一个apk程序,从而在该设备出厂时就自带该程序。

      从编译中枢的角度来讲,增加项目就是告诉编译中枢一些信息,这些信息包括:

  • 这个项目的target名称是什么?
  • 这个项目的输出类型是什么?比如:apk、jar包等
  • 这个项目对应的variant是什么?

有了这些信息后,编译中枢就知道如何编译该项目,并将输出的目标打包到不同的variant产品分类中。

一、给Android源码增加一个C项目

下面说明如何增加一个C项目。

首先,需要选择一个目录,本例可以选择external目录。

接着,需要给该项目定义一个target名称,这个target名称必须是全局唯一的,这里可以定义为helloMake。该工程很简单,只包含一个main.c文件,其内容如下:

#include <stdio.h>#include <stdlib.h>#include "hello.h"int main(){makePrintf("helloMake");return 0 ;}
hello.h文件内容如下:

#include <stdio.h>#include <stdlib.h>#ifndef _HELLO_H#define _HELLO_Hvoid makePrintf(char* str){printf("%s" , str);}#endif
添加这2个文件后,需要编写一个Android.mk文件,其内容如下:

LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_SRC_FILES := \main.cLOCAL_C_INCLUDES += $(LOCAL_PATH)LOCAL_MODULE := helloMakeLOCAL_MODULE_TAGS := enginclude $(BUILD_EXECUTABLE)
该mk文件中需要注意以下几点:

1、所有的C/C++原文件必须手动添加,因为编译中枢并没有提供一个能够自动从当前目录下寻找所有C/C++文件列表的函数。

2、由于C语言中会使用到include命令,因此,必须在mk文件中指定头文件的路径,仅需指定项目中包含的特别路径,而不需要指定系统头文件路径。因为系统头文件路径在编译中枢中已经设置好了,具体是在config.mk文件中设定的,如以下代码所示。如果要添加一些特别的系统路径,可以更该build/core/config.mk文件中SRC_HEADERS的值。


3、该项目使用的TAG值为eng,因此,仅当用户指定的产品类别是eng时才会包含该项目。如果要让所有类别的产品都包含该项目,可以将TAG值设置为optional,并在相应的product的配置文件中的PRODUCT_PACKAGES变量中包含该项目即可。./vendor/xxxx/build/product/xxxx_sdk.mk

4、然后就可以编译SDK,完成后,将新的system.img耍人设备,启动./adb shell,在命令行下,直接调用helloMake,程序将输出helloMake。


二、给Android源码增加一个apk项目

      添加一个apk项目可能是很多应用工程师经常遇到的问题,下面来介绍如何添加一个apk项目,该过程的原理和添加C项目相同,只是apk项目中相关的编译变量名称和C项目稍有不同。

      首先,假设已经在Eclipse下新建了一个名称为HelloAPK的Android应用项目,下面要做的就是要把这个项目移植进Android源码中。前面曾经说过,编译中枢会搜索Android根目录下除out目录外的所有子目录,并找出Android.mk文件作为一个子项目。因此理论上可以将HelloAPK项目放在任何目录下,只不过为了目录的清晰,厂商一般习惯于将自己定义的项目放到vendor下的相应目录中。

      然后,删除HelloApk目录下的bin和gen目录,因为这2个目录是Eclipse编译的输出目录,而其对Android编译系统而言是多余的,它甚至会认为这是2个源码目录。从这点上看,编译中枢似乎需要改进一下,它应该能够自动排除APK项目下的bin和gen目录。

      接下来,就需要新建一个Android.mk文件,并将其放到HelloAPK目录下,该Android.mk的内容如以下代码所示。

LOCAL_PATH:= $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE_TAGS := optionalLOCAL_SRC_FILES := $(call all-java-files-under, src)#LOCAL_SDK_VERSION := currentLOCAL_PACKAGE_NAME := bright-yinjkLOCAL_CERTIFICATE := platforminclude $(BUILD_PACKAGE)include $(call all-makefiles-under,$(LOCAL_PATH))
以上.mk文件说明如下:

LOCAL_MODAL_TAGS 用于指定该项目的标签值,对于应用类子项目而言,只能指定为3种情况,分别为:optional、tests、eng,这与C项目是相同的,本例中使用的是optional。因此,对于实体设备必须在devices/haiii/k/k.mk文件中包含该项目,否则K产品将不会包含该,如以下代码所示,

PRODUCT_PACKAGES := \        heoolMake \        HelloAPK
对于模拟器需要在vendor/hisxxx/build/product/hitv_sdk.mk文件中增加如下代码:

# thirdparty packages for devicePRODUCT_PACKAGES += \com.tencent.qqpinyin \bright-yinjk
LOCAL_SRC_FILE用于指定该项目中的JAVA源码,编译中枢提供了一个函数,可以直接遍历指定目录下的所有JAVA文件,从而不必手工列出所有的JAVA原文件,而C项目中没有类似功能的脚本函数。

LOCAL_PACKAGE_NAME:用于描述APK项目的名称,而C项目中用的是LOCAL_MODULE_NAME,注意区分。

LOCAL_SDK_VERSION:用于指定该APK项目所需的SDK版本,current代表了当前Android源码的版本。

LOCAL_CERTIFICATE:用于指定该APK项目将使用何种签名文件签名最后生成的apk文件。系统中一共包含4种签名文件,分别如下:

  • platform      FrameWork源码最后将生成一个Jar包,该Jar包默认使用该类型签名
  • shared        一些系统应用程序使用该类型签名,比如Contacts等
  • user             一些私有项目使用该签名
  • tests             调试过程中使用该签名

至于使用何种签名取决于项目的需要,一般当需要和特定的程序共享数据库资源时,两个项目必须拥有相同的签名。

最后,使用include包含BUILD_PACKAGE命令宏告诉编译中枢该项目的目标是一个apk程序。


以上介绍的是以源码的方式添加一个项目,有些时候可能还需要以一个apk文件的方式添加一个项目,在这种情况下,本质上添加的不是一个项目,而仅仅是一个文件。前面讲过,一个product中包含的项目分为3种,其中最后一种就是私有的项目或者文件,而这种方式实际上就是私有的文件。因此,需要在product相关的脚步文件中声明该product中包含apk文件。本例中就应该在k.mk文件中添加以下代码,其中赋值的源路径是主机系统上的路径,而目标路径是设备上的路径,两者使用冒号分割,如下:

PRODUCT_COPY_FILES := \      vendor/haiii/k/helloapk/helloapk.apk:/system/app
        该段代码仅仅是将HelloApk.apk复制到最终设备的/system/app目录下,如果想给apk进行签名怎么办?对不起,编译中枢没有单独提供这个功能,也就是说,再包HelloApk.apk复制到源码中前,应该事先给apk进行签名。如果开发中真的有这种需求,可以尝试增加一个BUILD_PACKAGE_WITHAPK的命令宏,就像BUILD_PACKAGE一样。用户可以在Android.mk文件中使用include命令包含该宏,然后在该命令宏的定义中手工实现对apk的签名。


原创粉丝点击