这两天有一个新的功能需求要实现, 要在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 |
|