AndroidStudio 的 JNI 工程创建与调用
1.新建一个 Android 工程
写一个 JNI 工具类:JNITools.java
package com.example.jnitest;
public class JNITools {
public static native String getStringFromJNI();
}
2.Activity的xml文件里给布局 添加一个 id
<?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>
3.在MainActivity调⽤写好的 JNI⽅法
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());
}
}
此时因为没有 native实现,运行会报错: java.lang.UnsatisfiedLinkError: No implementation found for
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)
4.Native实现——编译 JNI⽂件
MakeProject或者 RebuildProject之后,到 app下的 build⽂件夹找到 class所在⽬ 录;
进⼊到包名的上级⽬录,运⾏:javah -jni com.example.jnitest.JNITools
⽣成⼀个 com_example_jnitest_JNITools.h
⽂件,com.example.jnitest.JNITools是 你 JNI⼯具类所在引⽤,可根据实际情况修改。
com_example_jnitest_JNITools.h ⽂件源代码:
/* 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
jni_tool.c源代码:
#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
⾥⽅法名保持⼀致
5.cd到 jni⽬录,运⾏ 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
文件 。
6.添加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)
7.引用so
添加完成后,再次 cd到 jni⽬录,运⾏ ndk-build
,会⽣成 libs⽂件夹和对应的 so库。
生成了libs对应的so库之后,需要在app的build.gradle
文件里引用so路径。
build.gradle
android {
sourceSets{
main{
jniLibs.srcDirs+=['src/main/java/libs'] }
}
}
7.加载so
最后,在JNITools里面加载so文件
package com.example.jnitest;
public class JNITools {
static {
System.loadLibrary("jni_tool");
}
public static native String getStringFromJNI(); }
8.运行
最后,sync一下代码,然后运行,界面就会显示出c代码里输出的文案:
Hellow World,这是我的 NDK的第⼀⾏ 代码
以上流程亲测可用,欢迎指正!
我的博客即将同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=36dabq4yjfswo
会编程,了不起。羡慕