android JNI是连接android Java部分和C/C++部分的纽带,完整使用JNI需要Java代码和C/C++代码。其中C/C++代码用于生成库文件,Java代码用于引用C /C++库文件以及调用C/C++方法。

android Java部分代码:

/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.example.android.simplejni;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class SimpleJNI extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView tv = new TextView(this);
// int sum = Native.add(2, 3);
int minus = Native.minus(10, 3);
tv.setText("10-3 = " + Integer.toString(minus));
setContentView(tv);
}
}

class Native {
static {
// The runtime will add "lib" on the front and ".o" on the end of
// the name supplied to loadLibrary.
System.loadLibrary("simplejni");
}

static native int add(int a, int b);
static native int minus(int a, int b);
}

Java代码说明: 1)SimpleJNI是一个activity的类对象,在该类对象中生成调用JNI函数的类对象,同时调用JNI方法,最后将JNI方法的结果显示到标题栏上; 2)SimpleJNI是一个引用和声明JNI库和函数的类,其中System.loadLibrary();函数用来引用JNI库,默认JNI库放在 android系统的/system/lib/目录下; static native int add(int a, int b);为声明需要在java程序中使用的JNI库中的函数; JNI中java部分的代码到此就结束了,总结一下在java代码中需要做两件事: 1)使用System.loadLibrary()函数来引用JNI库; 2)声明调用JNI库的函数且前面添加native关键字;


android C/C++部分代码:

/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#define LOG_TAG "simplejni native.cpp"
#include <utils/Log.h>

#include <stdio.h>

#include "jni.h"

static jint
add(JNIEnv *env, jobject thiz, jint a, jint b) {
int result = a + b;
ALOGI("%d + %d = %d", a, b, result);
return result;
}

static jint
minus(JNIEnv *env, jobject thiz, jint a, jint b) {
int result = a - b;
ALOGI("%d - %d = %d", a, b, result);
return result;
}


static const char *classPathName = "com/example/android/simplejni/Native";

static JNINativeMethod methods[] = {
{"add", "(II)I", (void*)add },
{"minus", "(II)I", (void*)minus }
};

/*
* Register several native methods for one class.
*/
static int registerNativeMethods(JNIEnv* env, const char* className,
JNINativeMethod* gMethods, int numMethods)
{
jclass clazz;

clazz = env->FindClass(className);
if (clazz == NULL) {
ALOGE("Native registration unable to find class '%s'", className);
return JNI_FALSE;
}
if (env->RegisterNatives(clazz, gMethods, numMethods) < 0) {
ALOGE("RegisterNatives failed for '%s'", className);
return JNI_FALSE;
}

return JNI_TRUE;
}

/*
* Register native methods for all classes we know about.
*
* returns JNI_TRUE on success.
*/
static int registerNatives(JNIEnv* env)
{
if (!registerNativeMethods(env, classPathName,
methods, sizeof(methods) / sizeof(methods[0]))) {
return JNI_FALSE;
}

return JNI_TRUE;
}


// ----------------------------------------------------------------------------

/*
* This is called by the VM when the shared library is first loaded.
*/

typedef union {
JNIEnv* env;
void* venv;
} UnionJNIEnvToVoid;

jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
UnionJNIEnvToVoid uenv;
uenv.venv = NULL;
jint result = -1;
JNIEnv* env = NULL;

ALOGI("JNI_OnLoad");

if (vm->GetEnv(&uenv.venv, JNI_VERSION_1_4) != JNI_OK) {
ALOGE("ERROR: GetEnv failed");
goto bail;
}
env = uenv.env;

if (registerNatives(env) != JNI_TRUE) {
ALOGE("ERROR: registerNatives failed");
goto bail;
}

result = JNI_VERSION_1_4;

bail:
return result;
}

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代码:
#
# Copyright (C) 2008 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

# This makefile shows how to build a shared library and an activity that
# bundles the shared library and calls it using JNI.

TOP_LOCAL_PATH:= $(call my-dir)

# Build activity

LOCAL_PATH:= $(TOP_LOCAL_PATH)
include $(CLEAR_VARS)

LOCAL_MODULE_TAGS := samples

LOCAL_SRC_FILES := $(call all-subdir-java-files)

LOCAL_PACKAGE_NAME := SimpleJNI

LOCAL_JNI_SHARED_LIBRARIES := libsimplejni

LOCAL_PROGUARD_ENABLED := disabled

LOCAL_SDK_VERSION := current

include $(BUILD_PACKAGE)

# ============================================================

# Also build all of the sub-targets under this one: the shared library.
include $(call all-makefiles-under,$(LOCAL_PATH))

需要注意的是: 1)JNI C/C++部分的代码需要在android源代码树上进行编译,编译完成后我的做法是直接将生成的.so通过adb push方法上传到android虚拟机的/system/lib/目录下; 2)java代码可以在eclipse下直接编译且在虚拟机上执行;
编译JNI C/C++部分代码(在android内核源代码根目录下): #make XXXX 之后在out/target/product/generic/system/lib/目录下生成XXX.so
需要源码的同学 :http://download.csdn.net/detail/tianyeming/9000955


更多相关文章

  1. android 划屏动画
  2. undefined reference to `android::Mutex::lock()'
  3. android listView 总结
  4. x86平台下 Android(安卓)系统的 Linux 部分的重启分析
  5. listview 常用智识总结
  6. android 使用mediaplayer播放报java.io.IOException: setDataSou
  7. python服务程序(调用摄像头查看视频和识别二维码)+ Android(安卓)
  8. node.js+Android(安卓)http请求响应
  9. android小注意

随机推荐

  1. 提高Linux安全性--hosts.allow, hosts.de
  2. Linux(七):常用命令-文件处理命令-目录处
  3. android启动后根文件系统分析
  4. Nessus-3.0.6【linux漏洞扫描工具】
  5. linux / vi 常用命令(ubuntu环境)
  6. Linux-自己创建动态库静态库
  7. 多队列网卡CPU中断均衡
  8. Linux系统编程——进程间通信:信号中断处
  9. Linux下安装mysql 出现依赖包冲突解决方
  10. ubi文件系统制作,还是"-c"选项的问题