NDK开发多模块的工作方式——设置、运用与思考

来源:互联网 发布:瑞芯微电子 知乎 编辑:程序博客网 时间:2024/04/28 18:37

本工程文件的下载链接:AVIPlayer工程文件

在多个NDK项目之间共享本地模块或者在你的本地模块中引入第三方模块时,你需要懂得NDK_MODULE_PATH的设置与运用:

举个例子,NDK工程目录下的jni文件夹下的Android.mk如下:

LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE    := AVIPlayerLOCAL_SRC_FILES := \PlayerActivity.cpp # Use AVILib static library LOCAL_STATIC_LIBRARIES += avilib_staticinclude $(BUILD_SHARED_LIBRARY)$(call import-module, transcode-1.1.5/avilib)

第9行表明要用到外来的静态库avilib_static,第13行说明外来的库要去目录transcode-1.1.5/avilib去找。

编译动态库时出现如下错误:

Android NDK: jni/Android.mk: Cannot find module with tag 'transcode-1.1.5/avilib' in import path    
Android NDK: Are you sure your NDK_MODULE_PATH variable is properly defined ?  

注:transcode-1.1.5/avilib是共享库的目录,在此目录下有源文件和用于编译该共享库的Android.mk文件,需要时可以在该目录下生成共享库。

上面的错误提示表明最上层的Android.mk在编译过程中找不到transcode-1.1.5/avilib路径。


1.

设置方法:

在环境变量里加上一条:

ANDROID_NDK_HOME = D:\ndkWin32\android-ndk-r9d

截图如下:



设置成功后,NDK_MODULE_PATH的默认值为目录%ANDROID_NDK_HOME%/sources,你可以在NDK安装目录下看一下,那儿确实有个叫做sources的文件夹。

前边错误提示是transcode-1.1.5/avilib找不到,那么我们就把文件夹transcode-1.1.5复制到目录%ANDROID_NDK_HOME%/sources下,就能正常编译了。


2.如果你为了便于查看外来的库的内容,需要把外来的库文件加到本工程目录下,可以通过增加NDK_MODULE_PATH来解决。

例如:

仍延续上面的例子,我们把transcode-1.1.5文件夹复制到工程的jni目录下,要让系统在编译时找到它需要我们在上边的Android.mk文件里增加这样一句:

$(call import-add-path,$(LOCAL_PATH))

意思是把当前目录(%jni/%)加到NDK_MODULE_PATH里,这样系统在默认目录%ANDROID_NDK_HOME%/sources下找不到所需要的库,就会自动在当前目录下查找。

编辑后的Android.mk内容如下:

LOCAL_PATH := $(call my-dir)$(call import-add-path,$(LOCAL_PATH))include $(CLEAR_VARS)LOCAL_MODULE    := AVIPlayerLOCAL_SRC_FILES := \PlayerActivity.cpp # Use AVILib static library LOCAL_STATIC_LIBRARIES += avilib_static# Use AVILib static library LOCAL_STATIC_LIBRARIES += avilib_staticinclude $(BUILD_SHARED_LIBRARY)# Import AVILib library module$(call import-module, transcode-1.1.5/avilib)

工程jni目录截图:


图中标示为1的文件夹就是我们复制过来的transcode-1.1.5文件夹,而Android.mk就是我们在前头更改的Android.mk文件。
或许你很好奇transcode-1.1.5/avlib里有什么东东,也就是我们引入的内容到底是什么,那么我附图如下:


可以看到transcode-1.1.5/avlib文件夹下有源文件和Android.mk文件,从该目录下的Android.mk文件的内容来看该文件夹下的内容在编译时要生成静态库avilib_static,这个要生成的静态库正是jni目录下的Android.mk文件所需要的,见其第9行:

# Use AVILib static library LOCAL_STATIC_LIBRARIES += avilib_static


另外提一下上边出现的3个逻辑部分(静态库avlib,动态库AVIPlayer,以及Java层)的工作方式,如下图所示


可以看到:1.avlib模块直接与AVIPlayer模块相关联,实际上AVIPlayer对avlib进行了封装,并提供了若干接口;

                   2.而AVIPlayer直接与Java层相关联,Java曾调入此共享库,并使用其接口;

                   3.avlib未直接与Java曾相关联,而是以AVIPlayer为联系的中介,AVIPlayer向Java层提供的接口实际上有avlib内的代码来做实际工作。

不过我想到了另一种工作方式,不知可不可行:avlib模块和AVIPlayer模块分别直接与Java层联系,示意图如下:

当然还有另一种基于上一种工作方式的方式,区别在于avlib模块和AVIPlayer模块不但向Java曾提供服务,而且还以平等的地位相关联,即二者互相引用函数。




1 0
原创粉丝点击