这里使用手工编译的方式,Android Studio版本3.5.x。
1. 下载配置好NDK
2. 配置NDK环境变量
打开命令行,输入ndk-build, 如果有以下输出,则配置正确。
3. 打开Android Studio, 使用AS生成库的头文件(手工写也可以但是麻烦)
新建一个默认空项目:
新建一个类:
新建类后,修改代码如下:
public class funkey {
public native void func1();//测试1,无返回值
public native int func2();//测试2,返回int
public native String func3();//测试3..
}
生成所需要的头文件又两种方法:
1.手工编译:
在命令行中切换到funkey.java所在目录 cd D:\workspace\ndkx02\app\src\main\java\cn\appnet\ndkx02
javac funkey.java (注:这里需要提前将java路径写入到系统环境变量里面)
生成 funkey.class.
进入:D:\workspace\ndkx02\app\src\main\java> 执行命令: javah -jni cn.appnet.ndkx02.funkey
生成 cn_appnet_ndkx02_funkey.h
2.使用External Tool脚本
Name: NDK-PreBuild (这个可以随便写)
Description: javah javac ( 这个可以随便写)
Program: $JDKPath$\bin\javah.exe
Arguments: -classpath . -jni -d d:\NDK\jni $FileClass$
Working directory: $ModuleFileDir$\src\main\Java
保存后,在类名右键选择 NDK-Prebuild, 然后就会在D:\NDK\jni下生成头文件
以上的ndkx02工程,只是为了制作这个头文件,后面使用会新建一个工程。
下面编写和编译库文件:
1. 在d:\ndk\jni下新建 Android.mk 和 funkey.c
Android.mk 内容如下:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := funkey
LOCAL_SRC_FILES := funkey.c
LOCAL_LDLIBS = -llog
include $(BUILD_SHARED_LIBRARY)
Application.mk (这个文件可以不写)
APP_PLATFORM := android-16
funkey.c内容如下:
#include <jni.h>
#include "cn_appnet_ndkx02_funkey.h"
JNIEXPORT void JNICALL Java_cn_appnet_ndkx02_funkey_func1(JNIEnv *env, jclass jclazz)
{
return;
}
JNIEXPORT jint JNICALL Java_cn_appnet_ndkx02_funkey_func2(JNIEnv *env, jclass jclazz)
{
return 1;
}
JNIEXPORT jstring JNICALL Java_cn_appnet_ndkx02_funkey_func3(JNIEnv *env, jclass jclazz)
{
return (*env)->NewStringUTF(env, "M_OK");
}
进入命令行切换到:d:\ndk\jni下
d:\NDK\jni>ndk-build
Android NDK: APP_PLATFORM not set. Defaulting to minimum supported version android-16.
[arm64-v8a] Compile : funkey <= funkey.c
[arm64-v8a] SharedLibrary : libfunkey.so
[arm64-v8a] Install : libfunkey.so => libs/arm64-v8a/libfunkey.so
[armeabi-v7a] Compile thumb : funkey <= funkey.c
[armeabi-v7a] SharedLibrary : libfunkey.so
[armeabi-v7a] Install : libfunkey.so => libs/armeabi-v7a/libfunkey.so
[x86] Compile : funkey <= funkey.c
[x86] SharedLibrary : libfunkey.so
[x86] Install : libfunkey.so => libs/x86/libfunkey.so
[x86_64] Compile : funkey <= funkey.c
[x86_64] SharedLibrary : libfunkey.so
[x86_64] Install : libfunkey.so => libs/x86_64/libfunkey.so
下面是使用库:
将刚才编译出的库放入如下路径:D:\workspace\nkd001\app\libs
新建类funkey, 包名需要和上一个工程文件相同 cn.appnet.ndkx02
funkey.java
package cn.appnet.ndkx02;
public class funkey {
static {
System.loadLibrary("funkey");
}
public native void func1();
public native int func2();
public native String func3();
}
加入:
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}
修改MainActivity.java
package cn.app.nkd001;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import cn.appnet.ndkx02.*;
public class MainActivity extends AppCompatActivity {
funkey fk = new funkey();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void OnBtnClick1(View view){
fk.func1();
}
public void OnBtnClick2(View view){
int iResult = fk.func2();
System.out.println(iResult);
}
public void OnBtnClick3(View view){
String strResult = fk.func3();
System.out.println(strResult);
}
}
修改activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/Btn1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="32dp"
android:onClick="OnBtnClick1"
android:text="btn1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/Btn2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="32dp"
android:onClick="OnBtnClick2"
android:text="btn2"
app:layout_constraintStart_toEndOf="@+id/Btn1"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/Btn3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="32dp"
android:onClick="OnBtnClick3"
android:text="btn3"
app:layout_constraintStart_toEndOf="@+id/Btn2"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>