JNI
Posted 嘉禾世兴
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JNI相关的知识,希望对你有一定的参考价值。
交叉编译
在一个平台下,编译出另一个平台能够执行的二进制的代码
平台:windows,mac os,linux
处理器:x86,arm,mips
交叉编译的原理
源代码->编译->链接->可执行程序
模拟其他平台的特性
交叉编译的工具链
多个工具的集合,一个工具使用完后接着调用下一个工具
常见工具
NDK:native developement kit:开发jni必备,就是模拟其他平台特性来编译代码的工具
CDT:C/C++ developement tools:高亮显示c语言关键字
cygwin:一个模拟器,可以再windows下运行linux指令
NDK目录结构
docs:帮助文档
build/tools:linux的批处理文件
platforms:编译c代码需要使用的头文件和类库
prebuilt:预编译使用的二进制可执行文件
sample:jni的使用例子
source:ndk的源码
toolchains:工具链
ndk-build.cmd:编译打包c代码的一个指令
* 使用C语言实现本地方法
1. 在项目根目录下创建jni文件夹
2. 在jni文件中创建一个c文件
3. 在java代码中,创建一个本地方法helloFromC
//native关键字 public native String helloFromC();
4. 在jni中定义函数实现这个方法,函数名必须为
//返回值 报名_类名_方法名(参数参照例子) jstring Java_com_itheima_helloworld1_MainActivity_helloFromC(JNIEnv* env, jobject obj)
5. 返回一个字符串,用c定义一个字符串
char* cstr = "hello from c";
6. 把c的字符串转换成java的字符串
jstring jstr = (*env)->NewStringUTF(env, cstr); return jstr;
7. 在jni中创建android.mk文件
8. 在c文件中添加<jni.h>头文件
9. 在jni文件夹下执行ndk-build.cmd指令
10. java代码中加载so类库,调用本地方法(so是C语言的类库)
static{ //加载打包完毕的so类库 System.loadLibrary("hello"); }
代码
MainActivity
public class MainActivity extends Activity { static{ //加载打包完毕的so类库 System.loadLibrary("hello"); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } public void click(View v){ Toast.makeText(this, helloFromC(), 0).show(); } //定义一个本地方法,方法体由c语言实现 public native String helloFromC(); }
Hello.c
#include <stdio.h> #include <stdlib.h> #include <jni.h> jstring Java_com_itheima_helloworld1_MainActivity_helloFromC(JNIEnv* env, jobject obj){ //c语言的字符串 char* cstr = "hello from c"; //把C语言的字符串转换成java的字符串 // jstring (*NewStringUTF)(JNIEnv*, const char*); // jstring jstr = (*(*env)).NewStringUTF(env, cstr); jstring jstr = (*env)->NewStringUTF(env, cstr); return jstr; }
Android.mk
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) #编译生成的文件的类库叫什么名字 LOCAL_MODULE := hello #要编译的c文件 LOCAL_SRC_FILES := Hello.c include $(BUILD_SHARED_LIBRARY)
* 实现两个数相加
public class MainActivity extends Activity { static{ System.loadLibrary("hello"); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } public void click(View v){ Toast.makeText(this, "3+5的和为" + add(3, 5), 0).show(); } public native int add(int i, int j); }
Android.mk
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := hello LOCAL_SRC_FILES := Hello.c include $(BUILD_SHARED_LIBRARY)
Hello.c
#include <jni.h> jint Java_com_itheima_helloworld2_MainActivity_add(JNIEnv* env, jobject obj, jint i, jint j){ return i + j; }
APP_ABI := all //支持arm、mips、x86等所有架构
* javah
1.7:在src目录下执行javah 包名.类名
1.6:在bin/classes目录下执行
* 配置NDK路径
perference->android->ndk
addtools->add native tool 可以自动生成jni文件夹
以上是关于JNI的主要内容,如果未能解决你的问题,请参考以下文章