Java知识分享网 - 轻松学习从此开始!    

Java知识分享网

Java1234官方群25:java1234官方群17
Java1234官方群25:838462530
        
SpringBoot+SpringSecurity+Vue+ElementPlus权限系统实战课程 震撼发布        

最新Java全栈就业实战课程(免费)

springcloud分布式电商秒杀实战课程

IDEA永久激活

66套java实战课程无套路领取

锋哥开始收Java学员啦!

锋哥开始收Java学员啦!
当前位置: 主页 > Java文档 > 安卓技术相关 >

Android java和C互相调用 PDF 下载


分享到:
时间:2020-05-14 16:37来源:http://www.java1234.com 作者:小锋  侵权举报
Android java和C互相调用 PDF 下载
失效链接处理
Android java和C互相调用 PDF 下载

本站整理下载:
 
相关截图:
 
主要内容:

一,CMakeLists 
 
英文文档:https://cmake.org/documentation/
中文文档:https://www.zybuluo.com/khan-lau/note/254724
1,路径配置,在buildGradle的android层目中进行配置例如:
externalNativeBuild {
    cmake {
        path "src/main/cpp/CMakeLists.txt"
        version "3.10.2"
    }
}
 path配置cmake的引用路径,version配置cmake的版本
2,添加库,在cmakeList中调用add_library函数
     里面传入三个参数
  第一个是要引入的库别名,第二个是库的类型,是静态库还是动态库。在Android中是不能引用静态库的也就是.dll后缀的库,所以第二个参数只要是引入第三方的.so库都是写“SHARED”,第三个是通过什么样方式引入进来,第三方的一般都是通过包含进来,所以第三个参数基本也是固定的都是写“IMPORTED”。
add_library后,就要设置.so的详细路径了,通过set_target_properties()函数来设置;该函数也是要传入三参数来指定.so库的路径。第一个参数和add_library的第一个参数一样,不过这里的库别名要和add_library的库别名要一致,要不然在编译时会报找不到库的错误。第二个参数是固定的,都是写“ PROPERTIES IMPORTED_LOCATION”主要用来指定库的引入方式。都是通过本地引入。第三个就是库的具体路径,这个不能写错,如果写错了,编译时也同样会找不到库的。只要是引入第三方的库使用add_library就要使用set_target_propeties这个组合,所以它们是成对出现的。
 
3,编译我们自己在项目中写的c/c++文件
调用方式和上面的add_library方法类似,前两个参数和上面传入的是一样的,最后一个参数写对应我们的c++的文件路径,可以写多个路径,如下:
add_library( # Sets the name of the library.
        main-lib
 
        # Sets the library as a shared library.
        SHARED
 
        # Provides a relative path to your source file(s).
        main-lib.cpp
        runoobtest.cpp)
这里就不用set_target_propeties()
4,下面一个函数是find_library
这个方法是用来寻找系统库的,如果有用用到系统库就要调用这个函数
第一个参数是库的别名,第二个参数表示该库在系统ndk中的名字如下:
# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.
 
find_library( # Sets the name of the path variable.
        log-lib
 
        # Specifies the name of the NDK library that
        # you want CMake to locate.
        log)
 
 
   5,下一个方法是target_link_libraries,依赖的库
如果是系统的库要用这个格式${库的名字}。
如下:
# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.
 
target_link_libraries( # Specifies the target library.
        native-lib
 
        # Links the target library to the log library
        # included in the NDK.
        ${log-lib})
 
target_link_libraries( # Specifies the target library.
        main-lib
        # Links the target library to the log library
        # included in the NDK.
        ${log-lib}
        )
 
 
 
 
 
二,java调用层C代码流程
   第一种方式静态注册:
   1,首先加载共享库,加载库一般是在在静态代码块中进行:
 static {
    System.loadLibrary("native-lib");
}
 
    2,在Java中声明native方法
public native String stringFromJNI();
   3,实现原生方法
 #include <jni.h>
#include <string>
#include <android/log.h>
 
extern "C" JNIEXPORT jstring JNICALL
Java_com_test_jni_MainActivity_stringFromJNI(
        JNIEnv *env,
        jobject /* this */) {
    std::string hello = "Hello from C++";
    __android_log_print(ANDROID_LOG_ERROR,"TEST","HELLO ....... native lib");
    return env->NewStringUTF(hello.c_str());
}
为了找到c代码中对应的方法,需要要Java关键字开头,在方法前面加上包名,并且以下划线隔开。上面的stringFromJjni声明在了com.test.jni这个包名的MainActivity里面。
这样在java代码里就可以调用stringFromJni这个方法了
第二种方式:动态注册
1,和静态注册一样,先加载共享库
static {
    System.loadLibrary("dynamic-lib");
}
2,在java中声明native方法
public native int sum(int x, int y);
public native String getNativeString();
3,在c代码中中添加回调函数JNI_OnLoad方法,loadLibrary会执行该方法。
然后在JNI_OnLoad方法中调用方法RegisterNatives就完成注册了如下:
JNIEXPORT int JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
    JNIEnv *env;

 

------分隔线----------------------------

锋哥公众号


锋哥微信


关注公众号
【Java资料站】
回复 666
获取 
66套java
从菜鸡到大神
项目实战课程

锋哥推荐