因为本人以前是做C++开发的,所以就想着把以前的一些现成的东西移至到Android平台,经过查阅,Android通过jni技术和C/C++交互,索性学习一下jni。
下面是我做的第一个jni小程序,作为学习例程,供大家参阅。
我用的工具是Android Studio
首先,新建一个项目JniTest
包名为 android.example.com.jnitest
如下图(项目新建后未做任何修改)
新建一个Java文件
命名为MyJni 如下图
此时目录结构为
修改MyJni.java文件
package android.example.com.jnitest;
public class MyJni {
//加载的so库名
static {
System.loadLibrary("JniTest");
}
//native接口
public static native String sayHelloToJni();
}
调出命令终端
(也可通过Alt + F12)
生成class文件
通过cd 切换到 MyJni.java所在目录,如下图
执行 javac MyJni.java
不料,报错: 'JAVAC' 不是内部或外部命令,也不是可运行的程序 或批处理文件
经过查证,这是因为电脑没装jdk或者没把jdk加入到系统环境变量
我的电脑是因为没装 ,所以就下载了一个,下载链接如下
http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
我下载的版本如下图
添加到系统环境变量
找到安装目录(可通过查找javac.exe文件位置),复制目录并添加到系统环境变量 ,如下图
注意,系统环境变量 中的每个目录之间需要用分号隔开,末尾不需要分号
重启Android Studio
继续生成class文件
javac MyJni.java
这一步如果报错: 错误: 编码GBK的不可映射字符
就执行下面的命令
javac -encoding UTF-8 MyJni.java
成功后会生成一个MyJni.class文件
生成头文件
通过cd 切到java目录执行
javah -jni android.example.com.jnitest.MyJni
会生成一个.h文件
注:命令中的 android.example.com.jnitest 是包名, MyJni 是刚才新建的java文件名
新建jni文件夹
实现头文件接口
把刚才生成的头文件拷贝到 jni文件夹, 并在jni文件夹中新建一个.c文件 命名为hello.c
在hello.c中包含头文件并实现头文件的接口
目录结构如下
hello.c如下
#include "android_example_com_jnitest_MyJni.h"
JNIEXPORT jstring JNICALL Java_android_example_com_jnitest_MyJni_sayHelloToJni(JNIEnv *env, jclass jobj)
{
return (*env)->NewStringUTF(env,"hello jni");
}
修改配置
1.local.properties 文件
原内容(自动生成)
sdk.dir=C\:\\Users\\Administrator\\AppData\\Local\\Android\\Sdk
ndk.dir=C\:\\Users\\Administrator\\AppData\\Local\\Android\\Sdk\\ndk-bundle
修改后
sdk.dir=C\:\\Users\\Administrator\\AppData\\Local\\Android\\Sdk
ndk.dir=C\:\\Users\\Administrator\\AppData\\Local\\Android\\sdk\\ndk\\android-ndk-r10e
用自动生成的ndk 路径不会生成库文件
我就重新下载了一个 ,把安装完的包android-ndk-r10e放到了sdk\ndk\ 目录下
下载链接 https://pan.baidu.com/s/1qTAI6V1vfL37WQzZAYpmYA
2.gradle.properties 文件中添加一行
启用ndk
android.useDeprecatedNdk=true
3.build.grade文件添加代码
moduleName 是 MyJni.java 中加载的库名
ndk {
moduleName "JniTest"
abiFilters "armeabi", "armeabi-v7a", "x86"
}
添加的位置
编译
Rebuild Project 之后会生成libJniTest.so库,如图
调用
在MainActivity中定义一个 TextView , 显示sayHelloToJni接口的返回结果
TextView view = (TextView) findViewById(R.id.view);
view.setText(MyJni.sayHelloToJni());