首页 > 编程语言 >在Androidstudio 中 通过jni java 和c++相互调用实现方法

在Androidstudio 中 通过jni java 和c++相互调用实现方法

时间:2023-06-27 14:11:05浏览次数:49  
标签:java NativeAPI c++ Androidstudio so env stringFromJNI LOGI

在Androidstudio 中 通过jni java 和c++相互调用实现方法
1.创建 java native方法类
public class NativeAPI {
private static final String TAG = APP_TAG + "TestJni ";
static {
System.loadLibrary("testnative");
}

//从c++ so 中获取字符串
public native String stringFromJNI();
//c++ so 中回调的java方法
public void callBackFromNative(String strFromNative) {
Log.i(TAG, "callBackFromNative() strFromNative:" + strFromNative);
}
}
2.生成c++头文件
2.1.进入java NativeAPI.java所在目录,执行命令,会生成.NativeAPI.class 到 classfile目录下面
javac -d ./classfile/ NativeAPI.java
2.2.进入classfile目录,执行命令,会在classfile目录 生成jni目录,并生成NativeAPI.java的头文件
javah -d jni -jni com.android.demo.testnative.NativeAPI
3.编译so文件
进入module的src/main/目录,创建cpp目录,进入到cpp目录
3.1 拷贝com_android_demo_testnative_NativeAPI.h 到当前目录下面的public目录
3.2.拷贝生成的com_android_demo_testnative_NativeAPI.h 并修改文件名为com_android_demo_testnative_NativeAPI.cpp ,实现相关方法
JNIEXPORT jstring JNICALL Java_com_android_demo_testnative_NativeAPI_stringFromJNI
(JNIEnv * env, jclass obj) {

LOGI("NativeAPI_stringFromJNI 11");
//在c代码里面调用java代码里面的方法
// java 反射
//1 . 找到java代码的 class文件
// jclass (*FindClass)(JNIEnv*, const char*);
jclass javaclass = env->FindClass("com/android/demo/testnative/NativeAPI");
LOGI("NativeAPI_stringFromJNI 22");
if(javaclass==0){
//LOGI("find class error");
return env->NewStringUTF( "javaclass js null" );
}
LOGI("NativeAPI_stringFromJNI 33");
//LOGI("find class ");
//2 寻找class里面的方法
// jmethodID (*GetMethodID)(JNIEnv*, jclass, const char*, const char*);
jmethodID method1 = env->GetMethodID(javaclass,"callBackFromNative","(Ljava/lang/String;)V");
LOGI("NativeAPI_stringFromJNI 44");
if(method1==0){
//LOGI("find method1 error");
return env->NewStringUTF( "method1 js null" );
}
LOGI("NativeAPI_stringFromJNI 55");
//LOGI("find method1 ");
//3 .调用这个方法
// void (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...);
jstring parm1 = env->NewStringUTF( "参数1");
env->CallVoidMethod(obj,method1,parm1);
LOGI("NativeAPI_stringFromJNI 66");

return env->NewStringUTF( "test on tringFromJNI" );
}
3.3 创建CMakeLists.txt 文件中配置 需要引用的 头文件和c++ 文件等信息,需要生成的so库 名称等
3.4 进入module的build.gradle中 配置externalNativeBuild 引用CMakeLists.txt,
android {
externalNativeBuild {
cmake {
path "src/main/cpp/CMakeLists.txt"
}
}
}
3.5 然后assemble 编译 ,可以在 src/main/ 目录下生成jniLibs 目录,目录内包含生成的so文件,
PS:虽然可以生成so,但是有其他报错,生成完 so后,需要将externalNativeBuild 配置注释掉,然后再编译 module 引用对应的so

标签:java,NativeAPI,c++,Androidstudio,so,env,stringFromJNI,LOGI
From: https://www.cnblogs.com/adamli/p/17508703.html

相关文章

  • Java-hashcode与equals
    1.如果hashcode()不相同,两个对象一定不是同一个对象2.如果hashcode()相同,两个对象不一定上同一个对象,需要进一步判别equals3.如果equals相同,应当认为两个对象就是相同对象由于hashcode方法仅返回一个值,equals里面有若干逻辑,因此,部分集合类的判断中,会优先判断hashcode,如果相同再......
  • Java
    hashcode()、equals()1.如果hashcode()不相同,两个对象一定不是同一个对象2.如果hashcode()相同,两个对象不一定上同一个对象,需要进一步判别equals3.如果equals相同,应当认为两个对象就是相同对象由于hashcode方法仅返回一个值,equals里面有若干逻辑,因此,部分集合类的判断中,会优先......
  • C++太难学,怎么破?这本书给你指点迷津!
    2021年在线学习平台Springboard选出了最难学的编程语言TOP5,C++排在其中之一。C++难学的理由很多,比如它语法复杂,语法特性多,编程范式灵活,标准库内容过于基础,还要具备C语言基础等等。提起C++,它是由C语言大幅扩展而成,且用途非常广泛,例如用于Windows等操作系统、文字处理和......
  • java中 如何判断字符串为空
    在Java中,可以使用以下方法来判断字符串是否为空:使用length()方法判断长度是否为0:Stringstr="hello";if(str.length()==0){System.out.println("字符串为空");}使用isEmpty()方法判断是否为空字符串:Stringstr="hello";if(str.isEmpty()){System.out.printl......
  • java中 如何判断字符串为空
    在Java中,可以使用以下方法来判断字符串是否为空:使用length()方法判断长度是否为0:Stringstr="hello";if(str.length()==0){System.out.println("字符串为空");}使用isEmpty()方法判断是否为空字符串:Stringstr="hello";if(str.isEmpty()){System.out.printl......
  • C++ 容器比较 - Vector,
    C++容器STL准备了两类7种基本容器类型1.序列式容器:向量(vector)/双端队列(deque)/列表(List)/(string,array当做一种序列式容器)-与插入次序有关2.关联式容器(已序群集)-与插入次序无关(set,multiset,map,multiset)1.vectorvector(向量):是一种序列式容器,事实上和数组差不多,但它......
  • java springboot3 Property 'sqlSessionFactory' or 'sqlSessionTemplate' are requir
    老版本的mybatis-plus未适配springboot3解决办法:在pom.xml修改 mybatis-plus-boot-starter版本<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><vers......
  • java中 如何判断字符串为空
    在Java中,可以使用以下方法来判断字符串是否为空:使用length()方法判断长度是否为0:Stringstr="hello";if(str.length()==0){System.out.println("字符串为空");}使用isEmpty()方法判断是否为空字符串:Stringstr="hello";if(str.isEmpty()){System.......
  • java中 如何判断字符串为空
    在Java中,可以使用以下方法来判断字符串是否为空:使用length()方法判断长度是否为0:Stringstr="hello";if(str.length()==0){System.out.println("字符串为空");}使用isEmpty()方法判断是否为空字符串:Stringstr="hello";if(str.isEmpty()){Syste......
  • Java使用redis-Redis是并发安全的吗?
    大家都清楚,Redis 是一个开源的高性能键值对存储系统,被开发者广泛应用于缓存、消息队列、排行榜、计数器等场景。由于其高效的读写性能和丰富的数据类型,Redis 受到了越来越多开发者的青睐。然而,在并发操作下,Redis 是否能够保证数据的一致性和安全性呢?接下来小岳将跟大家一起来探......