本文转自: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就可以了。

更多相关文章

  1. C语言函数以及函数的使用
  2. Android 混淆代码有关问题总结
  3. Android 开发常用代码
  4. Android程序实现全屏代码
  5. [原]Android有用代码片断(六)
  6. android shape 代码实现按钮背景
  7. 获取Android SDK 源代码并在Eclipse中关联查看的方法(for sdk2.3
  8. Android开发实例源代码批量下载
  9. Android实现游戏摇杆的源代码

随机推荐

  1. Android,TextView的所有属性和方法
  2. 获取android顶部状态栏高度的两种方式
  3. 编译android源码
  4. Android根据 uri 获得文件真实路径
  5. 【Android 开发教程】屏幕方向的改变
  6. android内存泄露调试
  7. Android(安卓)Adapter的那些事
  8. Android 微光闪烁效果之更强Shimmer-andr
  9. Android ColorStateList使用方法
  10. 将已有的Android从Eclipse手动迁移到Andr