zoukankan      html  css  js  c++  java
  • Android如何调用第三方SO库

    问题描述:Android如何调用第三方SO库;
    已知条件:SO库为Android版本连接库(*.so文件),并提供了详细的接口说明;
    已了解解决方案:
    1.将SO文件直接放到libs/armeabi下,然后代码中System.loadLibrary("xxx");再public native static int xxx_xxx_xxx();接下来就可以直接调用xxx_xxx_xxx()方法;
    2.第二种方案,创建自己的SO文件,在自己的SO文件里调用第三方SO,再在程序中调用自己的SO,这种比较复杂,需要建java类文件,生成.h文件,编写C源文件include之前生成的.h文件并实现相应方法,最后用android NDK开发包中的ndk-build脚本生成对应的.so共享库;
    求解:
    1.上面两种方案是否可行?不可行的话存在什么问题?
    2.两种方案有什么区别?为什么网上大部都是用的第二种方案?
    3.只有一个*.so文件,并提供了详细的接口说明,是否可在ANDROID中使用它?

     
    首先要看这个SO是不是JNI规范的SO,比如有没有返回JNI不直接支持的类型。也就是说这个SO是不是可以直接当作JNI来调用。如果答案是否定的,你只能选第二个方案。

    如果答案是肯定的,还要看你是不是希望这个SO的库直接暴露给JAVA层,如果答案是否定的,你只能选第二个方案,比如你本身也是一个库的提供者。

    一般如果你只有SO,就说明这个是别人提供给你的,你可以要求对方给你提供配套的JAVA调用文件。

    1、这个要看这个SO是不是符合JNI调用的规范。还要看你自己的意愿。
    2、因为第二种方法最灵活,各种情况都可以实现。
    3、可以
     
    看能不能直接从JAVA调用的最简单的方法就是看SO里的函数名是不是Java_XXX_XXX_XXX格式的
    是就可以,你可以自己写一个配套的JAVA文件,注意一下SO函数名和JAVA函数名的转换规则,或者向SO提供方索要;
    不是的话就选第二种方案吧。
     
    1、检查所需文件是否齐全
    使用第三方动态库,应该至少有2个文件,一个是动态库(.so),另一个是包含
    动态库API声明的头文件(.h)
    2、封装原动态库
    原动态库文件不包含jni接口需要的信息,所以我们需要对其进行封装,所以我
    们的需求是:将libadd.so 里面的API封装成带jni接口的动态
    3、编写库的封装函数libaddjni.c
    根据前面生成的com_android_libjni_LibJavaHeader.h 文件,编写libaddjni.c,用
    来生成libaddjni.so

    Android中可能会用到第三方的软件包,这包括Java包.jar和Native包.so。jar包既可通过Eclipse开发环境集成,也可通过编译源码集成,看你的工作环境。

    假定自己开发的程序为MyMaps,需要用到BaiduMaps的库,包括baidumapapi.jar和libBMapApiEngine_v1_3_1.so。

    一、Eclipse中集成第三方jar包及.so动态库

    MyMaps工程下创建目录libs以及libs/armeabi,把baidumapapi.jar放在的libs/目录下,把libBMapApiEngine_v1_3_1.so放在libs/armeabi/下。

    Eclipse中把第三方jar包baidumapapi.jar打包到MyMaps的步骤:

    1. 右击工程,选择Properties;

    2. Java Build Path,选择Libraries;

    3. Libraries页面点击右面按钮“Add Library…”;

    4. 选择“User Library”,点击“Next”;

    5. 点击“User Libraries”按钮;

    6. 在弹出界面中,点击“New…”;

    7. 输入“User library name”,点击“OK”确认;

    8. 返回之后,选择刚刚创建的User library,右面点击“AddJARs”;

    9. 选择MyMaps/libs/下的baidumapapi.jar;

    10. 确认,返回。

    这样,编译之后,该jar包就会被打进MyMaps.apk中,libBMapApiEngine_v1_3_1.so也被打包在lib/armeabi/中。

    程序运行过程中,libBMapApiEngine_v1_3_1.so被放在/data/data/<yourAppPackage>/lib/下,加载动态库时系统会从程序的该lib/目录下查找.so库。

    二、源码中集成第三方集成jar包及.so动态库

    Android源码中MyMaps放在packages/apps下。MyMaps下创建目录libs以及libs/armeabi,并把baidumapapi.jar放在libs/,把libBMapApiEngine_v1_3_1.so放在libs/armeabi。

    2.1 修改Android.mk文件

    Android.mk文件如下:

    1. LOCAL_PATH:= $(call my-dir)
    2. include $(CLEAR_VARS)
    3. LOCAL_MODULE_TAGS := optional
    4. LOCAL_STATIC_JAVA_LIBRARIES := libbaidumapapi
    5. LOCAL_SRC_FILES := $(call all-subdir-java-files)
    6. LOCAL_PACKAGE_NAME := MyMaps
    7. include $(BUILD_PACKAGE)
    8. ##################################################
    9. include $(CLEAR_VARS)
    10. LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES :=libbaidumapapi:libs/baidumapapi.jar
    11. LOCAL_PREBUILT_LIBS :=libBMapApiEngine_v1_3_1:libs/armeabi/libBMapApiEngine_v1_3_1.so
    12. LOCAL_MODULE_TAGS := optional
    13. include $(BUILD_MULTI_PREBUILT)
    14. # Use the following include to make our testapk.
    15. include $(callall-makefiles-under,$(LOCAL_PATH))

    1 集成jar包

    LOCAL_STATIC_JAVA_LIBRARIES取jar库的别名,可以任意取值;

    LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES指定prebuiltjar库的规则,格式:别名:jar文件路径。注意:别名一定要与LOCAL_STATIC_JAVA_LIBRARIES里所取的别名一致,且不含.jar;jar文件路径一定要是真实的存放第三方jar包的路径。

    编译用BUILD_MULTI_PREBUILT

    2 集成.so动态库

    LOCAL_PREBUILT_LIBS指定prebuilt so的规则,格式:别名:so文件路径。注意:别名一般不可改变,特别是第三方jar包使用.so库的情况,且不含.so;so文件路径一定要是真实的存放第三方so文件的路径。

    编译拷贝用BUILD_MULTI_PREBUILT

    2.2 加入到GRANDFATHERED_USER_MODULES

    在文件user_tags.mk中,把libBMapApiEngine_v1_3_1加入到GRANDFATHERED_USER_MODULES中

    1. GRANDFATHERED_USER_MODULES +=
    2. libBMapApiEngine_v1_3_1

    user_tags.mk可以是build/core下的,也可以是$(TARGET_DEVICE_DIR)下的,推荐修改$(TARGET_DEVICE_DIR)下的。

    2.3 编译结果

    MyMaps.apk编译生成在out/target/product/<YourProduct>/system/app/下;

    libBMapApiEngine_v1_3_1.so放在out/target/product/<YourProduct>/system/lib/下,这也是系统加载动态库时搜索的路径。

     
  • 相关阅读:
    记一道乘法&加法线段树(模版题)
    2021CCPC网络赛(重赛)题解
    Codeforces Round #747 (Div. 2)题解
    F. Mattress Run 题解
    Codeforces Round #744 (Div. 3) G题题解
    AtCoder Beginner Contest 220部分题(G,H)题解
    Educational Codeforces Round 114 (Rated for Div. 2)题解
    Codeforces Global Round 16题解
    Educational Codeforces Round 113 (Rated for Div. 2)题解
    AtCoder Beginner Contest 182 F
  • 原文地址:https://www.cnblogs.com/android-blogs/p/5647286.html
Copyright © 2011-2022 走看看