本文转自:http://www.open-open.com/lib/view/open1324909652374.html

经过几天的努力终于搞定了android JNI部分,下面将我的这个小程序和大家分享一下。android JNI是连接android Java部分和C/C++部分的纽带,完整使用JNI需要Java代码和C/C++代码。其中C/C++代码用于生成库文件,Java代码用于引用C /C++库文件以及调用C/C++方法。

android Java部分代码:

01 jnitest.java
02   
03 package com.hello.jnitest;
04   
05    
06   
07 import android.app.Activity;
08   
09 import android.os.Bundle;
10   
11    
12   
13 public class jnitest extends Activity {
14   
15     /** Called when the activity is first created. */
16   
17     @Override
18   
19     public void onCreate(Bundle savedInstanceState) {
20   
21         super.onCreate(savedInstanceState);
22   
23         setContentView(R.layout.main);
24   
25         Nadd test = new Nadd();
26   
27         setTitle("The Native Add Result is "+String.valueOf(test.nadd(10, 20)));
28   
29     
30   
31 }
32   
33 Nadd.java
34   
35 package com.hello.jnitest;
36   
37    
38   
39 public class Nadd {
40   
41 static {
42   
43 System.loadLibrary("hello_jni");
44   
45 }
46   
47    
48   
49 public native int nadd(int a, int b);
50   
51 }

Java代码说明:
1)jnitest.java是一个activity的类对象,在该类对象中生成调用JNI函数的类对象,同时调用JNI方法,最后将JNI方法的结果显示到标题栏上;
2)Nadd.java是一个引用和声明JNI库和函数的类,其中System.loadLibrary();函数用来引用JNI库,默认JNI库放在 android系统的/system/lib/目录下;public nadd int nadd(int a, int b);为声明需要在java程序中使用的JNI库中的函数;
JNI中java部分的代码到此就结束了,总结一下在java代码中需要做两件事:
1)使用System.loadLibrary()函数来引用JNI库;
2)声明调用JNI库的函数且前面添加native关键字;
android C/C++部分代码:
01 #define LOG_TAG "hello-JNI"
02 #include <stdio.h>
03 #include <stdlib.h>
04 #include <unistd.h>
05 #include <sys/types.h>
06 #include <sys/stat.h>
07 #include <fcntl.h>
08 #include <assert.h>
09 #include "jni.h"
10 #include "JNIHelp.h"
11 #include "android_runtime/AndroidRuntime.h"
12 static jint com_hello_jnitest_jnitest_nadd(JNIEnv *env, jobject obj, jint a, jint b)
13 {
14 return (a * b);
15 }
16 static JNINativeMethod gMethods[] = {
17 {"nadd", "(II)I", (void *)com_hello_jnitest_jnitest_nadd},
18 };
19 static int register_android_test_hello(JNIEnv *env)
20 {
21 return android::AndroidRuntime::registerNativeMethods(env, "com/hello/jnitest/Nadd", gMethods, NELEM(gMethods));
22 }
23 jint JNI_OnLoad(JavaVM *vm, void *reserved)
24 {
25 JNIEnv *env = NULL;
26 if (vm->GetEnv((void **)&env, JNI_VERSION_1_4) != JNI_OK) {
27 printf("Error GetEnv\n");
28 return -1;
29 }
30 assert(env != NULL);
31 if (register_android_test_hello(env) < 0) {
32 printf("register_android_test_hello error.\n");
33 return -1;
34 }
35 return JNI_VERSION_1_4;
36 }

JNI C/C++代码说明:
1)JNI_OnLoad()函数。该函数在Java程序调用System.loadLibrary()时,被调用执行,用于向JavaVM注册JNI函数等。在本例中首先通过参数JavaVM(Java虚拟机指针)获取当前应用程序所在的线程,即:JNIEnv。再通过调用 android::AndroidRuntime::registerNativeMethods()注册native实现的函数指针。
2)JNI函数和Java调用函数的映射关系。使用JNINativeMethod将java调用的函数名与JNI实现的函数名联系在一起;
3)JNI函数实现;
Android.mk代码:
1 LOCAL_PATH := $(call my-dir)
2 include $(CLEAR_VARS)
3 LOCAL_PRELINK_MODULE := false
4 LOCAL_SRC_FILES := \
5 com_hello_jnitest.cpp
6 LOCAL_SHARED_LIBRARIES := \
7 libandroid_runtime
8 LOCAL_MODULE := libhello_jni
9 include $(BUILD_SHARED_LIBRARY)

需要注意的是:
1)JNI C/C++部分的代码需要在android源代码树上进行编译,编译完成后我的做法是直接将生成的.so通过adb push方法上传到android虚拟机的/system/lib/目录下;
2)java代码可以在eclipse下直接编译且在虚拟机上执行;
编译JNI C/C++部分代码(在android内核源代码根目录下):
#make libhello_jni
之后在out/target/product/generic/system/lib/目录下生成libhello_jni.so
上传libhello_jni.so到android虚拟机:
#adb push out/target/product/generic/system/lib/libhello_jni.so /system/lib
注意:此时有可能出现Out of Memory的错误提示。当出现如上错误提示时,需要使用#adb remount重新加载一下就可以了。
另外,也有可能直接使用eclipse启动android虚拟机时出现上述错误且使用#adb remount也出现的情况,此时需要手动启动android虚拟机,如:#emulator -avd xxx -partition-size 128,之后在使用#adb push就可以了。

转载于:https://www.cnblogs.com/freeliver54/archive/2012/02/03/2336621.html

[转]Android JNI使用方法相关推荐

  1. Android JNI使用方法,JNI机制详解

    Android JNI使用方法,JNI机制详解 JNI的出现使得开发者既可以利用Java语言跨平台.类库丰 富.开发便捷等特点,又可以利用Native语言的高效. JNI是JVM实现中的一部分,因此N ...

  2. Android JNI使用方法

    经过几天的努力终于搞定了android JNI部分,下面将我的这个小程序和大家分享一下.android JNI是连接android Java部分和C/C++部分的纽带,完整使用JNI需要Java代码和 ...

  3. android — JNI注册方法说明

    Jni中还可以采用RegisterNatives来注册jni的方法,注册以后的jni函数的命名可以不需要符合类似javah命令生成的函数的规则 RegisterNatives为JNIEnv的成员函数, ...

  4. Android Studio NDK环境配置及JNI使用方法

    1.前言 什么是NDK? NDK全称是Native Development Kit,NDK提供了一系列的工具,帮助开发者快速开发C(或C++)的动态库,并能自动将so和java应用一起打包成apk.N ...

  5. Android调用JNI本地方法跟踪目标代码

    正如Android调用JNI本地方法经过有点改变章所说跟踪代码是可行的,但是跟踪某些代码会出现anr,点击取消,还是不好运,有提高办法吗?回答是有(gdb还没试过,本文只讨论ida). 下面是我使用  ...

  6. Android JNI开发读取asserts目录中文件的方法

    Android Java层读取asserts目录中的文件: //获取asserts/test/目录下的所有文件名称 String test_path = "test"; int c ...

  7. android jni 调用 java_Android与JNI(二) ---- Java调用C++ 动态调用

    目录: 1. 简介 2. JNI 组件的入口函数 3. 使用 registerNativeMethods 方法 4. 测试 5. JNI 帮助方法 6. 参考资料 1. 简介 Android与JNI( ...

  8. java jni 数据类型_【Android JNI】Native层解析Java复杂数据类型HashMap

    前提 Java HashMap 是基于哈希表的 Map 接口的实现.此实现提供所有可选的映射操作,并允许使用null值和null键.HashMap是存放引用类型数据的容器,只能存放引用数据类型,不能存 ...

  9. Android JNI原理分析

    引言:分析Android源码6.0的过程,一定离不开Java与C/C++代码直接的来回跳转,那么就很有必要掌握JNI,这是链接Java层和Native层的桥梁,本文涉及相关源码: frameworks ...

最新文章

  1. Office OpenXML-Excel(一)
  2. Mybatis教程-实战看这一篇就够了
  3. 结构体struct timeval 和 struct timespec的定义
  4. Android数据库高手秘籍
  5. 怎么把数字替换成空格_剑指offer04:替换空格
  6. jquery datatable 获取当前分页的数据
  7. js中的转译_JavaScript中的填充和转译
  8. linux shell 批量清空,shell脚本批量删除docker镜像
  9. Assigning retained object to weak property object will be released after assignment
  10. 【光学】基于matlab夫琅禾费圆孔衍射【含Matlab源码 062期】
  11. Sentaurus SDE
  12. 从苦逼走向牛逼:阿里云的苦难辉煌
  13. 我的第一篇随笔-------吹起启程之风
  14. 无限制翻译PDF文件——低调使用
  15. android x86 uefi 安装教程,如何在Hyper-V上安装android-x86系统
  16. lr背景虚化_LR调色教程,用LR把夏天的颜色以图片的样式呈现出来
  17. python_cv2_图片黑白操作
  18. 当别人对自己有意见时,怎么处理?
  19. SELinux,查看 SELinux状态及关闭SELinux
  20. 差分详细讲解(C++)

热门文章

  1. 2022-2028年中国服装行业分析报告-产业规模现状与发展规划趋势
  2. 2022-2028年中国橡胶手套行业市场研究及前瞻分析报告
  3. Python 标准库之 shutil
  4. 55道常见的计算机面试题
  5. 【转载】首次作品展小结
  6. 反编译软件dnSpy中修改baml文件
  7. Pytorch学习记录-torchtext和Pytorch的实例( 使用神经网络训练Seq2Seq代码)
  8. Mobileye高级驾驶辅助系统(ADAS)
  9. 怎样训练YOLOv3
  10. 2021年大数据HBase(十六):HBase的协处理器(Coprocessor)