android源码平台下JAR包的引入与编译

6095人阅读 评论(7) 收藏 举报
分类:

转自:http://blog.csdn.net/sjz_iron/article/details/8348265

在应用开发过程中,常常需要引入第三方JAR包,或将自己的一些代码打包为JAR包以供其他应用使用,以下将描述这些操作的过程。需要注意的是,本文所述方法皆是在源码平台下的操作。

 

1.引入第三方JAR包

图1 测试程序根目录

        如图1,在应用AppsAut中需要引入第三方JAR包:appsaut.jar,我们将其放到libs目录中,Android.mk文件应如下编写:       

图2 Android.mk的编写

        图中带有红色下划线的第6行,第17行及第20行代码为引入第三方JAR包的核心代码,其含义如下。

        第6行:指定变量LOCAL_STATIC_JAVA_LIBRARIES的值,其值appsaut代表了所需引入的JAR包,appsaut只是一个别名,可任取,但必须要与第17中的保持一致;

        第17行:为LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES赋值。其中冒号前的appsaut要与第6行LOCAL_STATIC_JAVA_LIBRARIES的值相同,而冒号后则为此JAR 包的路径:即应用根目录libs目录中的appsaut.jar文件;

        第20行:调用BUILD_MULTI_PREBUILT命令对appsaut.jar进行预编译。

        经过以上三步,即可将JAR包appsaut.jar编译到最终的APK包中。在此需要说明的是,第三方appsaut.jar包为LOCAL_STATIC_JAVA_LIBRARIES,即.class文件归档后得到的JAR包,而BUILD_MULTI_PREBUILT命令的作用则是将静态JAVA类库压缩到.dex文件中--这是在android系统中所使用的JAVA包。

        注意:如果系统中存在与第三方JAR包相同的包,则此时我们的操作会失败。

 

2.编译自己的JAR包之一(失败)

        在平台中编译自己的JAR包,我们将源码目录appsaut存放在/external中。其目录结构如下:

 

图3 appsaut目录结构

        源码存放于src目录,通过编写Android.mk及appsaut.xml文件引导JAR包的编译,最终生成的JAR包不仅在平台中可用,同时可导入到手机系统/system/framework中,成为系统文件以供其他程序调用。

  1. LOCAL_PATH := $(call my-dir)  
  2. # the custom dex'ed emma library ready to put on a device.  
  3. # ============================================================  
  4. include $(CLEAR_VARS)  
  5. LOCAL_SRC_FILES := $(call all-java-files-under, src)  
  6. LOCAL_MODULE := appsaut  
  7. LOCAL_MODULE_TAGS := optional  
  8. include $(BUILD_JAVA_LIBRARY)  
  9.   
  10. #build the permission xml  
  11. #=============================================================  
  12. #MAKE_XML  
  13. include $(CLEAR_VARS)  
  14. LOCAL_MODULE := appsaut.xml  
  15. LOCAL_MODULE_TAGS := optional  
  16. LOCAL_MODULE_CLASS := ETC  
  17. LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/permissions  
  18. LOCAL_SRC_FILES := $(LOCAL_MODULE)  
  19. include $(BUILD_PREBUILT)  

代码段1 appsaut模块的Android.mk文件

以上代码为工程appsaut的Android.mk的内容。此段代码完成两件事情:编译JAR包与其对应的xml文件。代码01~07为变量赋值,第8行的代码通过调用命令BUILD_JAVA_LIBRARY将appsaut目录中的代码编译为JAR包,此命令的执行会在out/target/common/obj/JAVA_LIBRARIES/下生成目录appsaut_intermediates,此目录下便存放着编译生成的JAR和dex文件;同时,系统还会将目录JAR包复制到out/target/product/<product-name>/system/framework/路径下,如此以来,最终烧写到手机里的系统中的system/framework中便会存在此JAR包。

        但是仅存在JAR包是不够的,还需要与之对应的权限文件:即appsaut目录下的appsaut.xml文件,此文件的内容如下所示:

  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <permissions>  
  3.     <library name="com.test.appsaut" file="/system/framework/appsaut.jar"/>  
  4. </permissions>  

代码段2 appsaut.jar所对应的权限文件appsaut.xml

此文件中的标签<library>声明了一个JAR包,其中name指定了其名称,而file则指定了其存放路径。Android.mk文件中的代码10~19通过对appsaut.xml的编译,最终将其生成到out/target/product/<product-name>/system/etc/permissions/中,这样运行在手机里的程序能够在此文件的引导下使用我们编译的JAR包:appsaut.jar。与此同时,应用端的Android.mk文件中需要通过语句LOCAL_JAVA_LIBRARIES := appsaut.jar声明所使用的JAR包;而AndroidManifest.xml中则要添加如下语句:

                                         <uses-library name="com.test.appsaut"><uses-library>

来声明引用的JAR包。遗憾的是,尽管如此折腾了一番,结果却测试失败,将以上的JAR包,XML文件及APP应用PUSH到机器上,运行APP,无法找到JAR包中的类。可能是我本人的原因吧,终归是没有解决,OK,无奈之下不得不另谋他法,于是便有了下文。

 

3.将自己的代码编入android.jar包

        将手机ROOT后,进入到system/framework目录,可以看到存在framework.jar文件,此JAR包即android框架层的核心API,我们可以将自己的代码编入此JAR包从而成为系统API,如此则可由上层APP任意调用我们的代码--事实上是扩展了系统的API。

        首先,将我们的代码存放到android源码的frameworks/base目录下,需要注意的是,代码的目录结构必须为mylib/java/android/mylib(假设我们的代码均由JAVA写成);

        其次,修改build/core/pathmap.mk文件,在变量FRAMEWORKS_BASE_SUBDIRS后添加我们的代码,如下图所示:

图4 将代码编入android.jar

        最后,编译framework.jar(命令为:mmm frameworks/base),并将其替换掉手机中的system/framework/framework.jar,我们自己的代码便成为了系统API。

 

4.将自己的代码编入ext.jar

        3中的方法固然可行,但总觉得不妥--除非我们真的是在定制系统,否则将自己的代码放置到external目录下编译方为上策。在浏览frameworks/base/Android.mk时,无意中看到了如下内容:

图5 编译ext.jar的代码

显然,在生成framework.jar的同时还将external下的部分代码编译生成了另一个JAR包:ext.jar(LOCAL_MODULE := ext),于是迅速进入手机里的system/framework目录,果然看到一个ext.jar文件,这就意味着我们可以将自己的代码放到external目录中并编译到ext.jar(从名字来看ext应该是extention的缩写吧,呵呵)

        首先,将代码放入external目录,此时的目录结构可任意,如mylib/src/com/test/mylib;

        其次,在图5所示代码中,将我们的代码路径添加到变量ext_dirs中,如下图所示:

图6 将自己的代码编入到ext.jar中

        最后,重新编译ext.jar(命令依然是mmm frameworks/base),并将得到的ext.jar替换掉手机中的system/framework/ext.jar。

        注意:在编译应用程序时,如果此APP用到了ext.jar中的代码,需要在Android.mk文件中引入此JAR包:LOCAL_JAVA_LIBRARIES := ext。

 

5.BUILD_JAVA_LIBRARY与BUILD_STATIC_JAVA_LIBRARY

        在Android.mk中可通过调用include $(BUILD_JAVA_LIBRARY)和include $(BUILD_STATIC_JAVA_LIBRARY)来分别生成目标设备上的共享JAVA库与静态JAVA库。二者的区别在于静态JAVA库是由.class文件打包而成JAR包,它在任何一个JAVA虚拟机上都可以运行;而共享JAVA库则是在静态库的基础上进一步打包成的.dex文件,众所周知,dex是在android系统上所使用的文件格式。

        由以上结论可做出进一步的推论:即Android.mk中变量LOCAL_JAVA_LIBRARIES所指定的为android系统使用的dex类库;而LOCAL_STATIC_JAVA_LIBRARIES变量所指定的则是.class文件打包而成的JAR文件:即静态JAVA库。

        BUILD_STATIC_JAVA_LIBRARY会生成out/target/common/obj/JAVA_LIBRARIES/appsaut_intermediates目录及其下的JAR文件;而BUILD_JAVA_LIBRARY生成此目录的同时会将其中的JAR包复制到out/target/product/<product-name>/system/framework/中;除此之外,还存在BUILD_HOST_JAVA_LIBRARY命令则是在out/host/linux-x86/framework目录下生成相应的JAR包。分别使用此三条命令执行的结果如下所示:注意其中带有红色下划线的LOG信息。

图4 BUILD_STATIC_JAVA_LIBRARY的LOG信息

图5 BUILD_JAVA_LIBRARY的LOG信息

图6 BUILD_HOST_JAVA_LIBRARY的LOG信息

6.平台中添加预编译的JAR文件

        如果需要将已经存在的JAR文件添加到整个编译系统中,则相应的Android.mk文件需要如下配置(假设添加的JAR包为com.test.myjar):

图7 平台中添加预编译的JAR包

        注:

                (1)如代码所示,调用的命令为include $(BUILD_PREBUILT);

                (2)此jar包为LOCAL_JAVA_LIBRARIES,如代码所示:LOCAL_MODULE_CLASS := JAVA_LIBRARIES,即dex归档文件。

                (3)如果是STATIC_JAVA_LIBRARY是否也能如此添加?没进行相关验证,不得而知。如有兴趣,可自行验证。


查看评论

编译java静态库,java共享库

把这段复制到app下的Android.mk的最后,可以编译出java共享库,这个.jar除了生成在\out\target\common\obj\JAVA_LIBRARIES这里,还会copy到\out...
  • lin20044140410
  • lin20044140410
  • 2017年02月17日 18:27
  • 1162

android自定义静态jar包和动态jar包的编译、使用

android jar包的使用方法
  • bukker
  • bukker
  • 2016年06月14日 16:05
  • 5006

Android编译系统简要介绍和学习计划

在Android源码环境中,我们开发好一个模块后,再写一个Android.mk文件,就可通过m/mm/mmm/make等命令进行编译。此外,通过make命令还可制作各种系统镜像文件,例如system....
  • Luoshengyang
  • Luoshengyang
  • 2014年02月10日 01:02
  • 54175

Android -- 源码平台下JAR包的引入与编译

Android -- 源码平台下JAR包的引入与编译        在应用开发过程中,常常需要引入第三方JAR包,或将自己的一些代码打包为JAR包以供其他应用使用,以下将描述这些操作的过程。需...
  • csdn_of_coder
  • csdn_of_coder
  • 2017年03月21日 22:16
  • 1992

Android源码编译某个JAR包

在Android源码环境下,逐步执行下面的命令,否则不能识别make指令。1、framework.jarsource build/envsetup.shlunch38make framework(这里...
  • weixin_41987588
  • weixin_41987588
  • 2018年04月13日 14:25
  • 4

如何将android源码生成eclipse可用的jar包

以marvell的fm为例。 1.新建project 在eclipse上新建一project   选择General/Project  点击next,输入project name:将use def...
  • yuan1590
  • yuan1590
  • 2012年11月07日 23:19
  • 1770

android 源码环境下,编译apk时,导入第三方的jar包

源地址: http://www.cnblogs.com/hopetribe/archive/2012/04/23/2467060.html   Android.m...
  • u012242853
  • u012242853
  • 2015年01月20日 21:23
  • 1823

Android项目工程在源码环境下编译时引用第三方jar包

求解答,Android源码编译时怎样添加第三方jar包
  • Main_Stage
  • Main_Stage
  • 2013年09月26日 15:01
  • 2386

Android 源码编译的jar包

  • 2016年09月02日 13:34
  • 192B
  • 下载
    个人资料
    持之以恒
    等级:
    访问量: 58万+
    积分: 7577
    排名: 3580
    最新评论