三步走

第一步:创建一个Jni-demo项目。以图形方式一步步指引(just for 新手):

JavaCompiler 动态生成的类路径不对 java生成动态库so_java

JavaCompiler 动态生成的类路径不对 java生成动态库so_java 怎么链接ndk的库_02

JavaCompiler 动态生成的类路径不对 java生成动态库so_Java_03

JavaCompiler 动态生成的类路径不对 java生成动态库so_java_04

JavaCompiler 动态生成的类路径不对 java生成动态库so_Java_05

等待gradle build的完成,第一步就此结束。

备注:如果有的朋友遇到gradle太慢的情况,可以参考我的这篇博文,希望可以解决你的问题。

第二步:生成so库。

1、添加jni文件。

JavaCompiler 动态生成的类路径不对 java生成动态库so_so库_06

如此操作后,在\app\src\main目录下就多出了一个jni空文件夹。

比如我的就是在E:\AndroidProjects\JNI_Test\Jni-demo\app\src\main下多了一个jni空文件夹。

2、创建一个java类,在其中定义native方式。

JavaCompiler 动态生成的类路径不对 java生成动态库so_so库_07

如此操作后,会在MainActivity.java所在位置,新建一个名为Java_Interface.java的文件。

附上Java_Interface.java的源码:(简单实现一个加法和返回一个String)

package research.exam.com.jni_demo;
/**
* Created by Administrator on 2019/8/5.
*/
public class Java_Interface {
static {
System.loadLibrary("jniTest");
}
//functions declaration:
public native String GetHellString();
public native int Add(int n1, int n2);
}

JavaCompiler 动态生成的类路径不对 java生成动态库so_so库_08

3、由Java_Interface.java生成jni头文件。

备注:有关下图所示的NDK配置,请参考我的这个博客,希望可以帮助到你。

JavaCompiler 动态生成的类路径不对 java生成动态库so_so库_09

此时在我的项目的app/src/main/jni目录下就多了一个jni头文件,如下图所示:

JavaCompiler 动态生成的类路径不对 java生成动态库so_so库_10

4、在jni头文件所在目录添加三个文件,用来生成so库用的。它们是Android.mk Application.mk JNI.cpp三个文件。

附上相关源码,仅供参考学习。

Android.mk 文件源码如下所示:

LOCAL_PATH := $(call my-dir) #获取Android.mk所在目录
include $(CLEAR_VARS)
# 下面一句是用来指定so库生成位置的,感兴趣的朋友可以试试,确实可以改变so库生成位置。
# NDK_APP_DST_DIR=../../../../../SharedLibs/$(TARGET_ARCH_ABI)
LOCAL_MODULE := jniTest #指定生成so库的名称
LOCAL_SRC_FILES := JNI.cpp #指定生成so库所需源码文件
include $(BUILD_SHARED_LIBRARY) #说明生成的是动态so库(这句是废话)

Application.mk 文件源码如下所示:

# APP_ABI :=armeabi armeabi-v7a mips x86
APP_ABI :=armeabi-v7a #指定生成的so库适用的cpu架构,这个是最常见的一种。

JNI.cpp文件源码如下所示:

#include"research_exam_com_jni_demo_Java_Interface.h"
JNIEXPORT jstring JNICALL Java_research_exam_com_jni_1demo_Java_1Interface_GetHellString(JNIEnv *env, jobject obj)
{
return env->NewStringUTF("I love C++ Programming in Android.");
}
JNIEXPORT jint JNICALL Java_research_exam_com_jni_1demo_Java_1Interface_Add(JNIEnv *env, jobject obj, jint n1, jint n2)
{
return n1 + n2;
}

5、ndk-build产生so库。

JavaCompiler 动态生成的类路径不对 java生成动态库so_java 怎么链接ndk的库_11

第三步:编写简单UI,调用so库。

activity_main.xml 源码参考如下:(只是简单的一个UI界面,测试so库。)

MainAcitvity.java 文件源码如下:

package research.exam.com.jni_demo;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private Java_Interface mm_ji = null;
private TextView tv_show;
private Button btn_add;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_show = (TextView)findViewById(R.id.tv_show);
btn_add = (Button)findViewById(R.id.btn_add);
btn_add.setOnClickListener(this);
mm_ji = new Java_Interface(); //load so库
tv_show.setText(mm_ji.GetHellString());
}
@Override
public void onClick(View view) {
if(btn_add == view)
{
On_btn_add();
}
}
private void On_btn_add() {
int n1 = 3;
int n2 = 8;
tv_show.setText(mm_ji.Add(n1, n2) + "");
}
}

配置一下app目录下的build.gradle, 在android{}中添加如下代码:

sourceSets {
main {
jni.srcDirs = []
jniLibs.srcDirs = ['src/main/libs'] //指定apk安装时候要加载so库的位置,默认情况下的加载位置为:src/main/jniLibs
}
}

最后使用模拟器来仿真。给出仿真结果如下图:

JavaCompiler 动态生成的类路径不对 java生成动态库so_Java_12

JavaCompiler 动态生成的类路径不对 java生成动态库so_java_13

备注:javah和ndk-build方式生成so方式,注意事项,请参考这篇博客:

---- The End.