AndroidStudio 的 JNI 工程创建与调用
写一个 JNI 工具类:JNITools.java
package com.example.jnitest;
public class JNITools {
public static native String getStringFromJNI();
}
<?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">
<TextView
android:id="@+id/tv_show"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
package com.example.jnitest;
import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tvShow = findViewById(R.id.tv_show);
tvShow.setText(JNITools.getStringFromJNI());
}
}
2020-09-08 20:18:57.785 18756-18756/com.example.jnitest E/ AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.jnitest, PID: 18756
java.lang.UnsatisfiedLinkError: No implementation found for java.lang.String com.example.jnitest.JNITools.getStringFromJNI() (tried
Java_com_example_jnitest_JNITools_getStringFromJNI and
Java_com_example_jnitest_JNITools_getStringFromJNI__)
at com.example.jnitest.JNITools.getStringFromJNI(Native Method)
at com.example.jnitest.MainActivity.onCreate(MainActivity.java:16)
at android.app.Activity.performCreate(Activity.java:8085)
at android.app.Activity.performCreate(Activity.java:8073)
at
android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1320) at
android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3868) at
android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4074)
MakeProject或者 RebuildProject之后,到 app下的 build⽂件夹找到 class所在⽬ 录;
进⼊到包名的上级⽬录,运⾏:javah -jni com.example.jnitest.JNITools
⽣成⼀个 com_example_jnitest_JNITools.h
⽂件,com.example.jnitest.JNITools是 你 JNI⼯具类所在引⽤,可根据实际情况修改。
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h>
/* Header for class com_example_jnitest_JNITools */ #ifndef _Included_com_example_jnitest_JNITools
#define _Included_com_example_jnitest_JNITools
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_example_jnitest_JNITools
* Method: getStringFromJNI
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL
Java_com_example_jnitest_JNITools_getStringFromJNI (JNIEnv *, jclass);
#ifdef __cplusplus
}
#endif
#endif
#include "com_example_jnitest_JNITools.h"
JNIEXPORT jstring JNICALL
Java_com_example_jnitest_JNITools_getStringFromJNI
(JNIEnv *env, jobject obj){
return (*env)->NewStringUTF(env,"Hellow World,这是我的 NDK的第⼀⾏ 代码");
}
注意:include进来是
com_example_jnitest_JNITools.h
⽂件,⽅法名与com_example_jnitest_JNITools.h
⾥⽅法名保持⼀致
ndk-build
此时会报以下错误信息:
Android NDK: APP_PLATFORM not set. Defaulting to minimum supported version android-16.
Android NDK: WARNING: APP_PLATFORM android-16 is higher than
android:minSdkVersion 1 in /Users/maolijun298/AndroidStudioProjects/JniTest/ app/src/main/AndroidManifest.xml. NDK binaries will *not* be compatible with devices older than android-16. See https://android.googlesource.com/platform/ ndk/+/master/docs/user/common_problems.md for more information. Android NDK: Your APP_BUILD_SCRIPT points to an unknown file: /Users/ maolijun298/AndroidStudioProjects/JniTest/app/src/main/jni/Android.mk /Users/maolijun298/Library/Android/sdk/ndk/21.3.6528147/build/core/add- application.mk:88: *** Android NDK: Aborting... . Stop.
Android.mk
文件 。Android.mk
文件新建Android.mk文件到jni目录
Android.mk文件内容如下:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := jni_tool
LOCAL_SRC_FILES := jni_tool.c
include $(BUILD_SHARED_LIBRARY)
添加完成后,再次 cd到 jni⽬录,运⾏ ndk-build
,会⽣成 libs⽂件夹和对应的 so库。
生成了libs对应的so库之后,需要在app的build.gradle
文件里引用so路径。
build.gradle
android {
sourceSets{
main{
jniLibs.srcDirs+=['src/main/java/libs'] }
}
}
最后,在JNITools里面加载so文件
package com.example.jnitest;
public class JNITools {
static {
System.loadLibrary("jni_tool");
}
public static native String getStringFromJNI(); }
最后,sync一下代码,然后运行,界面就会显示出c代码里输出的文案:
Hellow World,这是我的 NDK的第⼀⾏ 代码