[笔记]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地址


相关文章
|
4天前
|
Android开发
Android JNI与CAN通信遇到的问题总结
Android JNI与CAN通信遇到的问题总结
26 1
|
6天前
|
Linux 编译器 Android开发
FFmpeg开发笔记(九)Linux交叉编译Android的x265库
在Linux环境下,本文指导如何交叉编译x265的so库以适应Android。首先,需安装cmake和下载android-ndk-r21e。接着,下载x265源码,修改crosscompile.cmake的编译器设置。配置x265源码,使用指定的NDK路径,并在配置界面修改相关选项。随后,修改编译规则,编译并安装x265,调整pc描述文件并更新PKG_CONFIG_PATH。最后,修改FFmpeg配置脚本启用x265支持,编译安装FFmpeg,将生成的so文件导入Android工程,调整gradle配置以确保顺利运行。
24 1
FFmpeg开发笔记(九)Linux交叉编译Android的x265库
|
19天前
Visual Studio 2022 中VLD库如何安装
Visual Studio 2022 中VLD库如何安装
21 1
|
5天前
|
Android开发
Android JNI 报错(signal 6 (SIGABRT), code -1 (SI_QUEUE), fault addr )
Android JNI 报错(signal 6 (SIGABRT), code -1 (SI_QUEUE), fault addr )
27 1
|
3天前
|
数据库 Android开发 开发者
安卓应用开发:构建高效用户界面的策略
【4月更文挑战第24天】 在竞争激烈的移动应用市场中,一个流畅且响应迅速的用户界面(UI)是吸引和保留用户的关键。针对安卓平台,开发者面临着多样化的设备和系统版本,这增加了构建高效UI的复杂性。本文将深入分析安卓平台上构建高效用户界面的最佳实践,包括布局优化、资源管理和绘制性能的考量,旨在为开发者提供实用的技术指南,帮助他们创建更流畅的用户体验。
|
4天前
|
存储 Java Linux
Android系统获取event事件回调等几种实现和原理分析
Android系统获取event事件回调等几种实现和原理分析
26 0
|
20天前
|
XML 开发工具 Android开发
构建高效的安卓应用:使用Jetpack Compose优化UI开发
【4月更文挑战第7天】 随着Android开发不断进化,开发者面临着提高应用性能与简化UI构建流程的双重挑战。本文将探讨如何使用Jetpack Compose这一现代UI工具包来优化安卓应用的开发流程,并提升用户界面的流畅性与一致性。通过介绍Jetpack Compose的核心概念、与传统方法的区别以及实际集成步骤,我们旨在提供一种高效且可靠的解决方案,以帮助开发者构建响应迅速且用户体验优良的安卓应用。
|
22天前
|
监控 算法 Android开发
安卓应用开发:打造高效启动流程
【4月更文挑战第5天】 在移动应用的世界中,用户的第一印象至关重要。特别是对于安卓应用而言,启动时间是用户体验的关键指标之一。本文将深入探讨如何优化安卓应用的启动流程,从而减少启动时间,提升用户满意度。我们将从分析应用启动流程的各个阶段入手,提出一系列实用的技术策略,包括代码层面的优化、资源加载的管理以及异步初始化等,帮助开发者构建快速响应的安卓应用。
|
22天前
|
Java Android开发
Android开发之使用OpenGL实现翻书动画
本文讲述了如何使用OpenGL实现更平滑、逼真的电子书翻页动画,以解决传统贝塞尔曲线方法存在的卡顿和阴影问题。作者分享了一个改造后的外国代码示例,提供了从前往后和从后往前的翻页效果动图。文章附带了`GlTurnActivity`的Java代码片段,展示如何加载和显示书籍图片。完整工程代码可在作者的GitHub找到:https://github.com/aqi00/note/tree/master/ExmOpenGL。
25 1
Android开发之使用OpenGL实现翻书动画
|
Java 测试技术 持续交付