JNI&NDK开发从入门到放弃(一)
1.安装与配置
借图
- 下载NDK
NDK下载配置完成之后,需要在gradle.properties文件中加上一行:
android.useDeprecatedNdk=true
安装NDK插件
在External Tools下配置两个非常有用的插件。进入Settings–>Tools–>ExternalTools,点击+号增加。
javah -jni命令,是根据java文件生成.h头文件的,会自动根据java文件中的类名(包含包名)与方法名生成对应的C/C++里面的方法名。下面是参数配置及其含义:
Program: JDKPath J D K P a t h \bin\javah.exe 这里配置的是JDK目录下的javah.exe的路径。
Parametes: -classpath . -jni -d ModuleFileDir M o d u l e F i l e D i r /src/main/jni FileClass F i l e C l a s s 这里 FileClass F i l e C l a s s 指的是要执行操作的类名(即我们操作的文件), ModuleFileDir M o d u l e F i l e D i r /src/main/jni表示生成的文件保存在这个module目录的src/main/jni目录下。
Working: ModuleFileDir M o d u l e F i l e D i r \src\main\java module目录下的src\main\java目录(不是很理解)。
使用方式:选中java文件—>右键—>External Tools—>javah-jni,将生成jni文件夹以及文件夹下的 包名.类名的.h头文件 (名字过长,我们可以自己重命名)。
ndk -build命令,是根据C/C++文件生成so文件的。下面是参数配置及其含义:
Program: F:\apk\sdk\ndk-bundle\ndk-build.cmd 这里配置的是ndk下的ndk-build.cmd的路径(根据实际情况填写)。
Working: ModuleFileDir M o d u l e F i l e D i r \src\main\
使用方式:选中C/C++文件—>右键—>ExternalTools—>ndk-build,将在main文件夹下生成libs文件夹以及多个so文件,我们可以移动至jniLibs目录下去。
2.创建实例
JniTest .java如下:
public class JniTest {
public native String getCLanguageString();
}
MainActivity.java如下:
public class MainActivity extends AppCompatActivity {
private TextView mTextView;
static {
System.loadLibrary("alatinJniLib");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView = (TextView) this.findViewById(R.id.test);
JniTest jni = new JniTest();
mTextView.setText(jni.getCLanguageString());
}
}
3.生成jni文件
1.对该文件执行javah -jni操作,生成对应的.h头文件;
2.新建一个C++文件,取名为jnitest.cpp,写上需要include的文件,从.h文件中复制方法过来;
jnitest.cpp如下:
#include "com_gg_alatin_JniTest.h"
JNIEXPORT jstring JNICALL Java_com_gg_alatin_JniTest_getCLanguageString
(JNIEnv *env, jobject obj){
return env -> NewStringUTF("Hello i am from JNI!");
}
3.在jni目录下增加两个文件,Android.mk和Application.mk;
Android.mk如下:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := alatinJniLib
// 设置模块的名称,即编译出来.so文件名
LOCAL_SRC_FILES := jnitest.cpp
// 指定参与模块编译的C/C++源文件名
include $(BUILD_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := hahaha
LOCAL_SRC_FILES := kekeke.cpp
include $(BUILD_SHARED_LIBRARY)
Application.mk如下:
APP_ABI := all
#APP_ABI:= armeabi armeabi-v7a x86 mips mips-r2 mips-r2-sf
#如果是普通arm处理器的Android手机,使用APP_ABI := armeabi;
#如果是x86处理器的,使用APP_ABI := x86,等等。
#如果APP_ABI := all,会编译所有指令的so
APP_STL := stlport_static
#NDK中C++标准库、STL的配置
#如未配置可能出现错误: fatal error: iostream: No such file or directory
4.对C++文件执行ndk-build操作,生成相应的so文件。
4.实例应用
将.so文件拷到主工程中,并在build.gradle中添加:
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}
ok,编译一下,运行。
5.最后
懒癌是大多数人的死敌。