[笔记]Visual Studio 2015 开发安卓so库JNI层——回调调用

简介: [笔记]Visual Studio 2015 开发安卓so库JNI层——回调调用

JNI调用java函数

Android JNI回调的三种方法

以下以静态方法为例

在app端创建回调方法

同上个例子 在com.example.helloso.MainActivity中

创建一个静态回调函数

public static void Callback_GetString(){
      Toast.makeText(mContext,"Callback_GetString",Toast.LENGTH_SHORT);
      Log.i(TAG,"Callback_GetString");
  }

在so代码中调用回调

在c++函数中调用回调函数

//该函数同上一节对应java native函数 com.example.helloso.MainActivity中HelloWorld()
jstring Java_com_example_helloso_MainActivity_HelloWorld(JNIEnv* env, jobject thiz) {
  LOGE("Start HelloWorld");
  Callback_TestVoid();
  LOGE("End HelloWorld");
  return env->NewStringUTF("Java_com_example_helloso_MainActivity_HelloWorld");
}

重写JNI_Onload函数 在载入时加载确定jni回调函数的ID

JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) {
  LOGI("Start JNI_OnLoad");
  JNIEnv* env;
  g_pJavaVM = vm;
  if (vm->GetEnv((void**)&env, JNI_VERSION_1_6) != JNI_OK) {
    return JNI_ERR; // JNI version not supported.
  }
  jclass  clz = env->FindClass(
    "com/example/helloso/Callback");
  g_jniHelperClz = (jclass)env->NewGlobalRef(clz);
  jmethodID  jniHelperCtor = env->GetMethodID(g_jniHelperClz,
    "<init>", "()V");
  jobject    handler = env->NewObject(g_jniHelperClz,
    jniHelperCtor);
  g_jniHelperObj = env->NewGlobalRef(handler);
  /
  g_methodTestVoid = env->GetStaticMethodID(g_jniHelperClz,
    "Callback_TestVoid", "()V");
  g_methodTestString = env->GetStaticMethodID(g_jniHelperClz,
    "Callback_TestString", "(Ljava/lang/String;)Ljava/lang/String;");
  g_methodTestByteArray = env->GetStaticMethodID(g_jniHelperClz,
    "Callback_TestByteArray", "([BI)[B");
  ///
  g_mainActivityObj = NULL;
  LOGI("End JNI_OnLoad");
  return  JNI_VERSION_1_6;
}

回调函数调用,先获得env,再通过全局jmethodID 调用java函数

void Callback_TestVoid() {
  LOGE("Star
  t Callback_TestVoid");
  JNIEnv *env;
  jint res = g_pJavaVM->GetEnv((void**)&env, JNI_VERSION_1_6);
  if (g_methodTestVoid != NULL) {
    LOGE("Start CallStaticVoidMethod");
    env->CallStaticVoidMethod(g_jniHelperClz, g_methodTestVoid);
  }
  LOGE("End Callback_TestVoid");
}

解释GetMethodID 获得函数地址

jmethodID GetMethodID(jclass clazz, const char* name, const char* sig);//获得函数地址
jmethodID GetStaticMethodID(jclass clazz, const char* name, const char* sig);//获得静态函数地址

sig表示标识函数格式

sig参数示意:  

boolean:Z

byte:B

char:C

short:S

int:I

long:J

float:F

double:D

void:V

[数组]:[+类型

Object对象:L包名/类名; 或包名/类名$标识嵌套类;

例子(方法 ->- 对应的sig):  

void M1(int A,int B) ->- “(II)V”

void M2(String S) ->- “(Ljava/lang/String;)V”  

void M3(int[] I) ->- “([I)V”  

String M4(String S) ->-"(Ljava/lang/String;)Ljava/lang/String"  

long M5(int I,Class class) ->- “(ILjava/lang/Class;)J”  

void M6(long LONG) ->- “(J)V”

番外 JNI java string到c/c++相关

JAVA和C++通过JNI传递中文乱码问题的解决方案

Android Native 开发之 NewString 与 NewStringUtf 解析

Android jni/ndk编程二:jni数据类型转换(primitive,String,array)

jni直接转byte_JNI jbyteArray转char*

String 
      (UTF-16)
          |
[java]    |
--------------------  JNI 调用
[cpp]     |
          v
       jstring 
       (UTF-16)
          |   
 +--------------------------+---------------------------+
 |GetStringChars/NewString  |GetStringUTFChars/NewStringUTF
 |                                                 |
 v                                                 v
wchar_t*                                         char*
(UTF_16)                                        (UTF-8)

总结

demo地址


相关文章
|
Android开发 Windows
Android studio 报错Connect to 127.0.0.1:8888 [/127.0.0.1] failed: Connection refused: connect(已解决)
这是一篇关于解决Android Studio报错“Connect to 127.0.0.1:8888 failed: Connection refused”的文章。问题通常因系统代理设置被Android Studio自动保存导致。解决方法是找到系统中Android Studio使用的gradle.properties文件(位于Windows的C:\Users\你的电脑用户名\.gradle或Mac的/Users/.{你的用户目录}/.gradle),删除或注释掉多余的代理配置后保存并重新Sync项目。希望此经验能帮助快速解决同类问题!
2579 36
|
Java Android开发
Android studio中build.gradle文件简单介绍
本文解析了Android项目中build.gradle文件的作用,包括jcenter仓库配置、模块类型定义、包名设置及依赖管理,涵盖本地、库和远程依赖的区别。
1070 19
|
开发工具 Android开发 iOS开发
如何在Android Studio中配置Flutter环境?
如何在Android Studio中配置Flutter环境?
3051 160
|
数据采集 JavaScript Android开发
【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
697 7
【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
|
Dart 前端开发 Android开发
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
536 4
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
前端开发 Java 编译器
当flutter react native 等混开框架-并且用vscode-idea等编译器无法打包apk,打包安卓不成功怎么办-直接用android studio如何打包安卓apk -重要-优雅草卓伊凡
当flutter react native 等混开框架-并且用vscode-idea等编译器无法打包apk,打包安卓不成功怎么办-直接用android studio如何打包安卓apk -重要-优雅草卓伊凡
634 36
当flutter react native 等混开框架-并且用vscode-idea等编译器无法打包apk,打包安卓不成功怎么办-直接用android studio如何打包安卓apk -重要-优雅草卓伊凡
|
NoSQL 编译器 C语言
C语言调试是开发中的重要技能,涵盖基本技巧如打印输出、断点调试和单步执行,以及使用GCC、GDB、Visual Studio和Eclipse CDT等工具。
C语言调试是开发中的重要技能,涵盖基本技巧如打印输出、断点调试和单步执行,以及使用GCC、GDB、Visual Studio和Eclipse CDT等工具。高级技巧包括内存检查、性能分析和符号调试。通过实践案例学习如何有效定位和解决问题,同时注意保持耐心、合理利用工具、记录过程并避免过度调试,以提高编程能力和开发效率。
659 1
|
SQL 人工智能 Dart
Android Studio的插件生态非常丰富
Android Studio的插件生态非常丰富
1054 1
|
Ubuntu Linux Android开发
Android Studio支持多种操作系统
Android Studio支持多种操作系统
841 1
|
数据可视化 开发工具 Android开发
Android Studio
Android Studio
989 1

热门文章

最新文章