我们在开发中经常要封装一些接口, 打包成jar包供app调用. 有时候我们需要打包一些具有系统API功能的jar包, 这时就需要在源码中去编译jar的源文件. 我在Android O的项目上开发应用程序时, 需要用到系统的一些功能, 想在源码中打包出一个功能丰富的jar包, 然后在IDE中使用, 比如Eclipse中使用, 这中间碰到了很多问题.
首先是编译动态jar包, Android.mk文件如下:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_MODULE := actionscanerapi
LOCAL_DEX_PREOPT := nostripping
include $(BUILD_JAVA_LIBRARY)
include $(call all-makefiles-under, $(LOCAL_PATH))
编译一个名叫actionscanerapi.jar的jar包, 生成在out/target/product/msm8953_64/system/framework/ 目录下, 包的结果如下:
可以看到, java文件都在classes.dex文件里面, 这种文件eclipse不认识, 将actionscanerapi.jar引入到eclipse会直接报错.
既然编译成动态jar包不行, 那就编译静态jar包, 编译静态jar包的中间产物里会有jar包, 于是将Android.mk修改如下:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_MODULE := actionscanerapi
LOCAL_DEX_PREOPT := nostripping
include $(BUILD_STATIC_JAVA_LIBRARY)
include $(call all-makefiles-under, $(LOCAL_PATH))
编译的中间产物在out/target/common/obj/JAVA_LIBRARIES/actionscanerapi_intermediates目录下:
可以看到生成的中间产物都是jack编译器生成的产物, 还需要先把jack编译器关闭, 在Android.mk中添加:
LOCAL_JACK_ENABLED := disabled
编译之后的产物如下:
查看classes.jar的目录结构, 终于像正常的jar包文件了:
在eclipse中引用此jar包, 提示: Conversion to Dalvik format failed with error 1. 转换成Dalvik虚拟机的格式错误, 看来还是编译器不兼容导致, Android O源码中的编译器编译的东西eclipse已经不能适应了, 我没有试过用Android Studio是否可用, 毕竟是官方的IDE, 兼容性应该更好一些, 有试过的人可以告诉我一下.
(注: 后来经过验证, 在Android Studio 中确实可用, 果然还是官方IDE牛叉)
最后实在没办法, 将代码放到Android5.1的源码中编译, 编译产物还是在:
out/target/common/obj/JAVA_LIBRARIES/actionscanerapi_intermediates里面, 编译出来的的jar包有classes.jar, javalib.jar等, 但是都是不可用的. 于是我将这些中间产物重新提取并打包:
提取class文件命令: jar -xvf classes.jar com/action/actionscaner/ScanerApi.class , 将我的API文件ScanerApi.class提取出来
重新打包jar命令: jar -cvf scanapi.jar ./com , 将上一步解压出来的文件夹重新打包成jar
这样制作出来的jar包就可以在eclipse中使用了. 同样的, 我在Android O的源码里使用上述两条命令制作jar包, 在eclipse里还是无法使用. 可能还是和编译器有关, 至少和 jar 这个工具有关.
这是我目前找到的唯一在源码中制作jar包并在eclipse中可以使用的方法, 如果还有更好的方法, 请给我留言. 谢谢.