三步走
第一步:创建一个Jni-demo项目。以图形方式一步步指引(just for 新手):
等待gradle build的完成,第一步就此结束。
备注:如果有的朋友遇到gradle太慢的情况,可以参考我的这篇博文,希望可以解决你的问题。https://blog.csdn.net/qq_41811438/article/details/97616483
第二步:生成so库。
1、添加jni文件。
如此操作后,在<项目存放位置>\app\src\main目录下就多出了一个jni空文件夹。
比如我的就是在E:\AndroidProjects\JNI_Test\Jni-demo\app\src\main下多了一个jni空文件夹。
2、创建一个java类,在其中定义native方式。
如此操作后,会在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);
}
3、由Java_Interface.java生成jni头文件。
备注:有关下图所示的NDK配置,请参考我的这个博客,希望可以帮助到你。https://blog.csdn.net/qq_41811438/article/details/97616166
此时在我的项目的app/src/main/jni目录下就多了一个jni头文件,如下图所示:
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库。
第三步:编写简单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
}
}
最后使用模拟器来仿真。给出仿真结果如下图:
备注:javah和ndk-build方式生成so方式,注意事项,请参考这篇博客:https://blog.csdn.net/qq_41811438/article/details/102524296
---- The End.