zoukankan      html  css  js  c++  java
  • [转]Android JNI使用方法

    本文转自: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就可以了。
  • 相关阅读:
    81. Search in Rotated Sorted Array II
    33. Search in Rotated Sorted Array
    26. Remove Duplicates from Sorted Array
    977. Squares of a Sorted Array
    碎片知识
    boost::shared_ptr
    faster-rcnn代码阅读-训练整体流程
    faster-rcnn代码阅读-数据预处理
    进栈与出栈
    jupyter-notebook添加python虚拟环境的kernel
  • 原文地址:https://www.cnblogs.com/freeliver54/p/2336621.html
Copyright © 2011-2022 走看看