转载请标注来源:

http://blog.csdn.net/shift_wwx/article/details/78951896

 

前言:

最近碰到一个问题,公司内部的app需要替换源生的app,也就是说不编译源生的app,而编译后的out下只能由公司指定的app,没有源生的app。例如,源生的Launcher2。

网上搜了一下,并没有多少相关的文章,后来就此问题研究了一下,这里做个总结,如果有哪里不对的请不吝赐教。

 

对于这个问题,有三种解决方案:

1、直接删掉Launcher2这个目录方案

2、Android中源生给出的替换方案

3、统一管理方案

 

 

1、直接删掉Launcher2这个目录方案

这是个暴力的解决办法,但是移植性、维护性差一些。如果有的板卡需要,有的不需要,这样就不能删除了。

这个方案有利有弊,结合工程管理方便来。

 

 

2、Android中源生给出的替换方案

这个方案Android源生是存在的,仔细看下build/core/*.mk 就会发现有个变量叫LOCAL_OVERRIDES_PACKAGES

这个变量跟LOCAL_PACKAGE_NAME一样,在app的Android.mk中添加需要替换掉什么app(让此app不参与编译)只需要设定这个变量即可。

例如,

Android中如何不编译源生模块_第1张图片

这里设定好LOCAL_OVERRIDES_PACKAGES 就可以让Launcher2不参与编译。

 

但是,这样修改有个缺点。如果是单个的应用,这样修改没有问题,但是如果是很多应用,那就需要修改每个应用的mk 文件。这就产生了第 3 中修改方案。

 

3、统一管理方案

对于第2点的方案似乎已经达到目的了,但是如果不是替换,而是简单的控制不让其参与编译,这个变量是无法设定的。

来看下这里统一管理的方案,在Android中的makefile中有个变量PRODUCT_PACKAGES,这个变量是控制模块是否参与编译,我们在device目录下看到很多这样的设定,这时候如果为了项目或者板卡维护,直接修改device下的PRODUCT_PACKAGES变量就可以了。但是有时候会看到有些模块不是在device下面控制,而是放在了build下面,这个时候为了项目维护性,不能直接修改build下的变量。

有了这样的顾虑,为了以后项目维护性,想了一个办法,那就是用一个变量统一管理,以后不管是什么项目不需要源生的或者device下面已经设定好的PRODUCT_PACKAGES,只需要设定这个变量就可以了。

 

首先来看下PRODUCT_PACKAGES是怎么使用的。

在build/core/product.mk中看到这样的一个变量:

Android中如何不编译源生模块_第2张图片

在makefile 中会将定义PRODUCT_PACKAGES的makefile通过 inherit-product或者 inherit-product-if-exists的函数传入。

 

来看下 inherit-product 函数:

Android中如何不编译源生模块_第3张图片

首先,通过normalize-paths 确定想要的path,这个函数最终调用的是一个python脚本,感兴趣可以跟一下。

接着,将_product_var_list中定义的字符串中每个子串为名字的变量后面加上后缀,这个后缀就是需要inherit的makefile的路径。

例如,这个makefile的路径为device/common/hehe.mk,那最后变量的后面会加上@inherit:device/common/hehe.mk,表示该变量继承自哪里。

从这里看,以后PRODUCT_PACKAGES这个变量后面会跟很多mk

第3步,将变量PRODUCTS.$(strip $(word 1,$(_include_stack))).INHERITS_FROM 加入inherit的makefile的路径(这里为device/common/hehe.mk)排序后重新赋值。

第4步,最后统一为ALL_PRODUCTS。

这其中有个地方需要另外研究,就是变量 _include_stack,详细看build/core/node_fns.mk 中的处理部分。

 

函数inherit-product-if-exists:

Android中如何不编译源生模块_第4张图片

这个函数会先判断inherit的makefile 是否存在。

 

上面只是前期的准备工作,主要的解析是在函数import-products中

Android中如何不编译源生模块_第5张图片

这里就不详细说明,有兴趣可以看下build/core/node_fns.mk 中的过程。

 

最终在main.mk中会做一个过滤:

Android中如何不编译源生模块_第6张图片

上面的第2点就是这样来的,详细第2点的解析可以看下package.mk中的运行过程。

 

所以,最后如果想要达到统一的管理,可以在这里做一个过滤,用一个变量统一管理。

假定这个变量的名字为PRODUCT_DEL_PACKAGES,表示需要删掉的module,那添加后的过滤代码为:

添加后编译就会把不需要编译的module去掉。

当然,这个变量是需要跟PRODUCT_PACKAGES添加到 _product_var_list 中,详细看 build/core/product.mk中:

Android中如何不编译源生模块_第7张图片

 

Android 的build 过程比较复杂,这里只针对这3中办法做个简单的总结,后期后持续总结build下编译过程。请大神不吝赐教。

 

 

参考:

http://blog.csdn.net/lewif/article/details/50014827

 

 

 

更多相关文章

  1. Android消息推送完美方案
  2. android dialog宽度无法填满屏幕解决方案
  3. 一个hello程序的android内核模块编译方法及在模拟器中进行测试结
  4. Linux下配置NDK、JDK环境变量
  5. android导出sqllist数据库要先配置adb.exe加到环境变量里
  6. 2018-06-02 mac上完整卸载删除:android studio方案
  7. AVD无法启动解决方案
  8. as 引用模块 ( android stdio modules )

随机推荐

  1. Android 5.1.1 源码目录结构
  2. Swing中引入Android的NinePatch技术,让Swi
  3. 那些年Android黑科技①:只要活着,就有希望
  4. Android(安卓)IPC
  5. 创业&Android
  6. Android开发者e周报 第6期
  7. android车载娱乐系统跟android平板的分析
  8. Android中自定义控件
  9. Missing styles. Is the correct theme c
  10. Android的Window类详解