第一个NDK程序
2011-03-04 11:36
183 查看
一、概述
【 为什么要使用JNI】重用已有的代码,这些代码用C/C++编写
提供程序运行效率
通常会在与硬件、操作平台交互时, 或者使用一些与Android平台无关的算法时用到JNI。
【文章目标】
认识如何为Native Code编写Java接口。
认识在JAVA程序中是如何访问C/C++代码的。
二、实例
Native Code实现了一个返回字符串"Hello world JNI!!!"的功能,JAVA调用了该方法,并将它打印到屏幕上。【效果图】
【实现步骤】
(1)编写带有native声明的方法的java类。
package enleo.jni; public class Jni { public native int add(); public native String getString(); }
(2)使用javac命令编译所编写的java类,生成Jni.class.
(3)使用javah-jni java类名生成扩展名为h的头文件
打开enleo_jni_Jni.h文件,自动生成了以下内容:
#ifndef _Included_enleo_jni_Jni #define _Included_enleo_jni_Jni #ifdef __cplusplus extern "C" { #endif /* * Class: enleo_jni_Jni * Method: add * Signature: ()I */ JNIEXPORT jint JNICALL Java_enleo_jni_Jni_add (JNIEnv *, jobject); /* * Class: enleo_jni_Jni * Method: getString * Signature: ()Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_enleo_jni_Jni_getString (JNIEnv *, jobject); #ifdef __cplusplus } #endif #endif
注意:这个文件是C/C++的头文件声明,它是(1)中建立的Java类的一个映射。当然,这个文件也可以通过手动生成,这不是好方法! 因为你不知道Java的数据类型与C/C++数据类型之间的映射关系。另外,在C/C++的实现文件里面的方法必须与.h文件所声明的一致。
(4)使用C/C++(或者其他编程想语言)实现本地方法。
enleo_jni_Jni.c
#include <stdio.h> #include <stdlib.h> #include "enleo_jni_Jni.h" int add(){ int x,y; x =100; y =100; return x+y; } JNIEXPORT jint JNICALL Java_enleo_jni_Jni_add(JNIEnv *env, jobject thiz) { return add(); } JNIEXPORT jstring JNICALL Java_enleo_jni_Jni_getString(JNIEnv *env, jobject thiz) { (*env)->NewStringUTF(env,"Hello world JNI!!!"); }
(5)将C/C++编写的文件生成动态连接库
1.编写Android.mk
LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := NewJNI LOCAL_SRC_FILES := enleo_jni_Jni.c include $(BUILD_SHARED_LIBRARY)
2.编写Application.mk
APP_PROJECT_PATH :=$(call my-dir)/project APP_MODULES := NewJNI
3.编译C/C++代码
【可能出现的问题】如果NDK的版本与SDK版本不兼容,会出现下面的提示
我的解决方法是修改了default.properties,将版本从7改为4,骗过了cygwin。
不过这种方法不推荐使用,大家最好还是下载合适的版本。
(6)调用动态库
调用System.loadLibrary("NewJNI");函数加载libNewJNI.so。
package enleo.HelloWorldJNI; import android.app.Activity; import android.os.Bundle; import android.widget.TextView; import enleo.jni.Jni; public class eHelloWorldJNI extends Activity { private TextView textView; static{ System.loadLibrary("NewJNI"); } /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Jni jni = new Jni(); int result = jni.add(); textView = (TextView)findViewById(R.id.tv); textView.setText(jni.getString()); } }
【可能出现的问题】UnsatisfiedLinkError
导致这种错误的原因是找不到库,或者找不到库函数。请检查修正后重新运行。
四、扩展
Java和NativeCode数据类型映射表相关文章推荐
- android之NDK(jni)开发笔记1——运行第一个NDK程序
- Android studio开发NDK,第一个NDK程序教程
- 第一个NDK程序
- 第一个NDK小程序之两个数的加法
- NDK 下第一个boost asio 网络程序测试成功
- 编写第一个NDK程序
- NDK-JNI实战(一) 在Android Studio运行第一个NDK程序
- Android NDK:②第一个NDK程序(创建步骤&一些问题)
- NDK-JNI实战教程(一) 在Android Studio运行第一个NDK程序
- Android NDK学习教程(一)--第一个NDK程序
- 第一个NDK程序 MyFirstNDK_app
- NDK-JNI实战教程(一) 在Android Studio运行第一个NDK程序
- 创建第一个NDK程序
- AndroidStudio上的第一个jni程序——NDK入门
- Android Studio运行第一个NDK程序
- NDK-JNI实战教程(一) 在Android Studio运行第一个NDK程序
- NDK开发之环境的搭建和开发第一个NDK程序
- NDK开发之——eclipse配置以及第一个NDK程序
- 编写第一个NDK程序