本博客主要是在Ubuntu 下开发,且默认你已经安装了Eclipse,Android SDK, Android NDK, CDT插件。

在Eclipse中添加配置NDK,路径如下Eclipse->Window->Preferences->Android->NDK ,选择NDK的路径,然后Apply即可。

新建一个名为AndroidJNI_MethodCall的Android工程,新建一个jni的文件夹,其目录下文件树列表如下:

├── jni
│   ├── Android.mk
│   ├── Application.mk
│   └── methodcall
│      ├── Android.mk
│      ├── logger.h
│      └── methodcall_jni.c

jni/Application.mk文件内容如下:

  1. APP_ABI := all

jni/Android.mk,主要用来指定顺序执行所有子文件夹下面的makefile文件,内容如下:

  1. include $(call all-subdir-makefiles)

jni/methodcall/Android.mk,主要用来指定需要编译出的动态库的名称,以及需要编译的源文件,内容如下:

  1. LOCAL_PATH := $(call my-dir)
  2.  
  3. include $(CLEAR_VARS)
  4.  
  5. LOCAL_MODULE := methodcall_jni
  6. LOCAL_SRC_FILES := methodcall_jni.c
  7.  
  8. LOCAL_LDLIBS := -llog
  9.  
  10. include $(BUILD_SHARED_LIBRARY)

jni/methodcall/logger.h 主要用来在JNI层打印日志,内容如下:

  1. #include <jni.h>
  2. #include <android/log.h>
  3.  
  4. /**
  5. * 定义log标签
  6. */
  7. #define TAG "jni_logger"
  8.  
  9. /**
  10. * 定义info信息
  11. */
  12. #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__)
  13.  
  14. /**
  15. * 定义debug信息
  16. */
  17. #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__)
  18.  
  19. /**
  20. * 定义error信息
  21. */
  22. #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__)

jni/methodcall/methodcall_jni.c,主要用来注册绑定java函数和native函数,以及java函数在c中相应函数的具体实现, 内容如下:

  1. #include "logger.h"
  2.  
  3. #ifndef NULL
  4. #define NULL ((void *) 0)
  5. #endif
  6.  
  7. /**
  8. * 获取数组的大小
  9. */
  10. #define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0])))
  11.  
  12. /**
  13. * 指定要注册的类,对应的完整的java类名
  14. */
  15. #define JNIREG_CLASS "com/clarck/jni/MethodCall"
  16.  
  17. JNIEXPORT void JNICALL native_Method(JNIEnv *env, jobject obj) {
  18. /*jclass cls = (*env)->GetObjectClass(env, obj);
  19. //在被给的类中方法执行一个查询。查询是依靠名字和方法的类型描述符。
  20. jmethodID mid = (*env)->GetMethodID(env, cls, "callback", "()V");
  21. if (NULL == mid) {
  22. return ;
  23. }
  24. LOGI("In C \n");
  25. //然后本地代码调用"CallVoidMethod"。"CallVoidMethod"调用一个实例方法,它返回一个 void类型。你传递一个对象(object),方法 ID 和实际参数
  26. (*env)->CallVoidMethod(env, obj, mid);*/
  27.  
  28. jclass cls = (*env)->GetObjectClass(env, obj);
  29. jmethodID mid = (*env)->GetStaticMethodID(env, cls, "_callback", "()V");
  30. if (NULL == mid) {
  31. return ;
  32. }
  33.  
  34. LOGI("In C \n");
  35. (*env)->CallStaticVoidMethod(env, cls, mid);
  36. }
  37.  
  38. /**
  39. * Java和JNI函数绑定
  40. */
  41. static JNINativeMethod method_table[] = {
  42. { "nativeMethod", "()V", (void*) native_Method },
  43. };
  44.  
  45. /**
  46. * 注册native方法到java中
  47. */
  48. static int registerNativeMethods(JNIEnv* env, const char* className,
  49. JNINativeMethod* gMethods, int numMethods) {
  50. jclass clazz;
  51. clazz = (*env)->FindClass(env, className);
  52. if (clazz == NULL) {
  53. return JNI_FALSE;
  54. }
  55.  
  56. if ((*env)->RegisterNatives(env, clazz, gMethods, numMethods) < ) {
  57. return JNI_FALSE;
  58. }
  59.  
  60. return JNI_TRUE;
  61. }
  62.  
  63. /**
  64. * 调用注册方法
  65. */
  66. int register_ndk_load(JNIEnv* env) {
  67. return registerNativeMethods(env, JNIREG_CLASS, method_table,
  68. NELEM(method_table));
  69. }
  70.  
  71. JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
  72. JNIEnv* env = NULL;
  73. jint result = -;
  74.  
  75. if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_4) != JNI_OK) {
  76. return result;
  77. }
  78.  
  79. register_ndk_load(env);
  80.  
  81. //返回jni的版本
  82. return JNI_VERSION_1_4;
  83. }

接着在Project中右键Android Tools->Add Native Support,最后java层调用如下:

  1. package com.clarck.jni;
  2.  
  3. import android.util.Log;
  4.  
  5. public class MethodCall {
  6. public native void nativeMethod();
  7.  
  8. public void callback() {
  9. Log.d("Test", "In Android");
  10. }
  11.  
  12. public static void _callback() {
  13. Log.d("Test", "In Android static");
  14. }
  15.  
  16. static {
  17. System.loadLibrary("methodcall_jni");
  18. }
  19. }
  1. package com.clarck.jni;
  2.  
  3. import android.app.Activity;
  4. import android.os.Bundle;
  5.  
  6. public class MainActivity extends Activity {
  7.  
  8. @Override
  9. protected void onCreate(Bundle savedInstanceState) {
  10. super.onCreate(savedInstanceState);
  11. setContentView(R.layout.activity_main);
  12.  
  13. MethodCall methodCall = new MethodCall();
  14. methodCall.nativeMethod();
  15. }
  16. }

执行Ctrl+B执行编译,运行工程即可。

Android NDK 学习之调用Java函数的更多相关文章

  1. Android NDK 学习之接受Java传入Object数组

    本博客主要是在Ubuntu 下开发,且默认你已经安装了Eclipse,Android SDK, Android NDK, CDT插件. 在Eclipse中添加配置NDK,路径如下Eclipse-> ...

  2. Android NDK 学习之接受Java传入的Int数组

    本博客主要是在Ubuntu 下开发,且默认你已经安装了Eclipse,Android SDK, Android NDK, CDT插件. 在Eclipse中添加配置NDK,路径如下Eclipse-> ...

  3. Android NDK 学习之接受Java传入的字符串

    本博客主要是在Ubuntu 下开发,且默认你已经安装了Eclipse,Android SDK, Android NDK, CDT插件. 在Eclipse中添加配置NDK,路径如下Eclipse-> ...

  4. Android jni c/c++线程通过CallVoidMethod调用java函数出现奔溃问题

    最近在移植网络摄像机里的p2p库到android平台,需要用到jni,最近在c线程了调用java函数的时候 出现一个问题,假如在同一个线程调用java函数是没问题的,但在一个c线程了调用java函数就 ...

  5. 一、Android NDK编程预备之Java jni简介

    转自:  http://www.eoeandroid.com/thread-264384-1-1.html 游戏开发 视频教程 博客 淘帖     论坛›eoe·Android应用开发区›Androi ...

  6. 三、Android NDK编程预备之Java jni入门创建C/C++共享库

    转自: http://www.eoeandroid.com/thread-264971-1-1.html 应网友回复,答应在两天前要出一篇创建C/C++共享库的,但由于清明节假期,跟朋友出去游玩,丢手 ...

  7. 二、Android NDK编程预备之Java jni入门Hello World

    转自:  http://www.eoeandroid.com/forum.php?mod=viewthread&tid=264543&fromuid=588695 昨天已经简要介绍了J ...

  8. Android NDK开发及调用标准linux动态库.so文件

    源:Android NDK开发及调用标准linux动态库.so文件 预备知识及环境搭建 1.NDK(native development Kit)原生开发工具包,用来快速开发C.C++动态库,并能自动 ...

  9. Android开发学习必备的java知识

    Android开发学习必备的java知识本讲内容:对象.标识符.关键字.变量.常量.字面值.基本数据类型.整数.浮点数.布尔型.字符型.赋值.注释 Java作为一门语言,必然有他的语法规则.学习编程语 ...

随机推荐

  1. CGI = MCC + MNC + LAC + CI

    CGI = MCC + MNC + LAC + CI 摘自:http://www.360doc.com/content/19/0801/10/65611272_852334484.shtml CGI是 ...

  2. ios开发将截图保存到相册

    - (void)loadImageFinished:(UIImage *)image { UIImageWriteToSavedPhotosAlbum(image, self, @selector(i ...

  3. WinForm,在另一个线程中更新Form中的数据(转)

    Form本身有线程,但对于一些耗时的操作,我们不希望在Form的线程中进行,因为会导致Form线程阻塞,产生假死的现象. 其他线程中操作Form中的控件,总出现“线程间操作无效: 从不是创建控件的线程 ...

  4. Ubuntu18.04下LAMP环境搭建

    可以安装安装Xampp,Xampp是一个集成的LAMP开发环境. 但是这只是对于一个刚安装好的系统来说的,但是很有可能我的电脑上面已经安装过Apache,或者安装过MySQL,或者安装过PHP了,或者 ...

  5. STM32驱动模数转换芯片ADS1120(基础知识篇)第1篇

    1. 先看下ADS1120的结构图,ADS1120是个比较奇葩的ADC模数转换器,因为比较适用于热电阻之类的温度采集器.看下图,有个MUX多路复用器,应该是选择两个差分信号去测试,通过输入多路复用器 ...

  6. Flutter中的日期插件date_format 中文 国际化 及flutter_cupertino_date_picker

    今天我们来聊聊Flutter中的日期和日期选择器. Flutter中的日期和时间戳 //日期时间戳转换 var _nowTime = DateTime.now();//获取当前时间 print(_no ...

  7. 2019年Java面试题基础系列228道(5)

    21.存在两个类,B 继承 A,C 继承 B,我们能将 B 转换为C 么?如 C = (C) B: 这属于强制类型转换,如果被转换的B实例不是C类型,会有异常 比如你的ABC分别对应动物,猫,黑猫. ...

  8. 【计算机视觉】目标检测之ECCV2016 - SSD Single Shot MultiBox Detector

    本文转载自: http://www.cnblogs.com/lillylin/p/6207292.html SSD论文阅读(Wei Liu--[ECCV2016]SSD Single Shot Mul ...

  9. 【JS】逻辑处理

    1.计算会员进度 const a = res.data.directCount(当前充值点券) / nextLevelData.map(item => item.direct_number(下一 ...

  10. 利用卷积神经网络处理cifar图像分类

    这是一个图像分类的比赛CIFAR( CIFAR-10 - Object Recognition in Images ) 首先我们需要下载数据文件,地址: http://www.cs.toronto.e ...