这两天有一个新的功能需求要实现,
要在Android原生代码的Settings(代码目录android/frameworks/base/core/java/android/provider)数据库添加一个新的数据项,
一个系统应用(独立于Android系统源码编译)需要引用该数据项. 那么,
怎么将新的数据项引用到系统应用中了? <! – more –>
备注: 以下所有的示例都基于Android Studio 3.2/操作系统Ubuntu 18.04.1
首先, 在Android源码中修改完成后, 执行本地编译,
在/android/out目录下,
找到编译产生的新的framework模块的jar包:
1 | out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes-full-debug.jar |
最开始, 打开该jar包,
将/android/provider/目录下的所有class文件复制到Android Studio中的SDK的platforms/android-23,
重新clean/build一次,
项目中对新建的数据项的符号引用立刻就正常了.但一提交到远程服务器,
后台编译出错, 提示找不到符号了~what!
马上就要发布版本了,
怎么办?只好硬着头皮找其他法子了…参考了网上已有的很多文档, 编译一直报错.
不得已开始想着要通过广播的形式来替换掉现有的通过ContentProvider的方式,
这样就避开修改Android SDK了, 但广播存在这么几个问题:
- 任何人都可以监听接收该广播, 安全性与性能都大打折扣;
- 如果接收方线程阻塞, 会导致广播超时, 造成应用ANR
整个需求的方案已经定了, 再去该明显会被打回的, 而且就该功能的实现而言,
只有在某个状态变化时, 才要求告知上层,
这个正是ContentProvider可以达成的逻辑. 转了一圈,
只好又回到原来的方案. 跟同事沟通了配置的方法, 编译终于通过,
但是验证测试时又碰到了问题….这里记录下来整个过程, 也算是为后来的Android
SDK定制积攒点经验.
添加framework.jar到AS
将编译好的Android框架层jar包framework.jar放到/app/libs/下面,
然后在应用app的配置build.gradle下面添加一个依赖项,
这里的provided表示该依赖只在编译时起作用,
不会把对应的jar文件编译到最终的APK中去:
1 | dependencies { |
将framework.jar设置为bootclass
为了让库生效, 需要在编译开始时,
将framework.jar设置为当前所有子项目的启动文件(boot
class):
1 |
|
同时,
还需要在app/build.gradle中添加一个编译的类路径(class
path):
1 |
|
网上的大部分资料都说到了这一步就好了, 但是这时看引用的Java文件中,
仍然提示找不到新的符号, 重新看了下网络上的教程,
原来还需要更改下app.iml中的引用先后顺序.
修改app.iml中的库引用顺序
app.iml包含了某个项目的信息以及依赖状态,
找到framework.jar以及Android SDK对应的<orderEntry>,
将framework.jar对应的调整到Android SDK之前就可以了:
1 |
|
在实际操作过程,
注意不要在app/build.gradle中添加如下两个配置,
不然编译虽然可以通过, 但是执行时会出现异常:
1 |
|