Android 通过JNI调用SO库

1.在自己项目创建本地方法:

Android 通过JNI调用SO库

2.手动创建本地方法fromJNIString()对应的.h头文件

  • 在电脑的cmd 或者AndroidStudio的Terminal中输入

javah -d E:\AndroidProject\JNI\HelloWorld\app\src\main\jni -classpath E:\AndroidProject\JNI\HelloWorld\app\src\main\java com.example.helloworld.MainActivity

  1. E:\AndroidProject\JNI\HelloWorld是我的项目路径       app\src\main\jni 要创建的.h头文件的输出路径 。
  2. -d E:\AndroidProject\JNI\HelloWorld\app\src\main\jni创建jni文件夹并指定.h输出目录。
  3. E:\AndroidProject\JNI\HelloWorld\app\src\main\javacom.example.helloworld.MainActivity包含本地方法(fromJNIString())的类的绝对                路    径,com.ang.ndkdemo.MainActivity  注意是包名+类名,不要写成了                                                                                    D:\Demo\NDKDemo\app\src\main\java\com\ang\ndkdemo\MainActivity

Android 通过JNI调用SO库

  • 执行以上命令之后:就在项目的main文件夹下创建了jni文件夹,并且在jni文件夹下自动创建了.h头文件;

Android 通过JNI调用SO库

  • 在jni目录下创建c或者c++文件

鼠标指针点到方法名(Android 通过JNI调用SO库)上,键盘按 “Alt”+“Enter”键,出来快捷菜单,选中 “Create function ….” 按“Enter”键确认。现在 在native-lib.cpp文件里就有这个方法了。我们这个方法是要返回一个字符串,所以在native-lib.cpp稍微修改一下这个方法。

Android 通过JNI调用SO库

名字可以跟.h的一致

Android 通过JNI调用SO库

添加.cpp文件内容

#include <com_example_helloworld_MainActivity.h>
#include <stdio.h>
JNIEXPORT jstring JNICALL Java_com_example_helloworld_MainActivity_getStringFromNative(JNIEnv *env, jclass jclass)
{
return env->NewStringUTF("I am From Native C");
}

配置build.gradle

Android 通过JNI调用SO库

在jni文件夹下新建Android.mk,内容如下:

LOCAL_PATH :=$(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE :=Java2c
LOCAL_SRC_FILES :=com_example_helloworld_MainActivity.cpp
include $(BUILD_SHARED_LIBRARY)

其中:LOCAL_MODULE :=Java2c中的Java2c为.so的名称。

LOCAL_SRC_FILES :=com_example_helloworld_MainActivity.cpp为手动新建的cpp

新建Application.mk,内容如下:

APP_ABI := all

配置build.gradle

Android 通过JNI调用SO库

在工程目录下的gradle.properties文件的末尾加上一句:Android.useDeprecatedNdk=true ;

手动编译.so文件

1.cmd 或者Android studio的Terminal 中进入jni的上一级目录

cd E:\AndroidProject\JNI\HelloWorld\app\src\main

2.输入ndk-build命令,在jni同级的目录中生成了一个libs文件夹,里面生成了各个cup架构对应的.so文件,

Android 通过JNI调用SO库

Android 通过JNI调用SO库

最后在MainActivity中加载我们生成的动态库:

public class MainActivity extends AppCompatActivity {

private TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView=(TextView) findViewById(R.id.sample_text);
textView.setText(getStringFromNative());
}
static {
        System.loadLibrary("Java2c");//生成的so名称
}

public native static String getStringFromNative();
}

启动程序运行后的页面为:

Android 通过JNI调用SO库