前言
Android 开发中难免会使用到 jni,实践中虽然简单,但也还是有不少坑点。上一节我们讲了如何生成 so 文件,接下来我们继续看看怎么在其他项目里使用我们生成的 so 库。
Android 如何生成 so 库 - 掘金 (juejin.cn)
新建项目
新建了一个 Empty Android 项目 SoUser,包名为com.me.souser。
在项目的 app 目录下新建 libs 文件夹,把我们的 so 文件拷贝进去,arm64-v8a 这个文件目录是因为我测试用的手机 cpu 架构为 arm64-v8a。
然后修改 build.gradle(:app) 文件,在 android 层级内加上 sourceSets 相关的内容,Gradle 就会从 libs 目录下查找并包含我们添加的本地库文件 libsotest.so。
android {
namespace 'com.me.souser'
compileSdk 34
// 省略无关
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}
}
加载 so 库并声明 jni 方法
这里需要确保 jni 方法签名和 so 库里的方法签名相同,也就是保证相同的类名和包名,不然会索引不到,报错类似 java.lang.UnsatisfiedLinkError: No implementation found for ...。
package com.me.sotest;
public class JniMethod {
// Used to load the 'sotest' library on application startup.
static {
System.loadLibrary("sotest");
}
public static native String stringFromJNI();
}
哈哈,显然就是把我们生成 so 库时的代码复制过来了。
测试调用 jni 方法
当在 TextView 成功显示出 Hello from C++ 的时候,就说明我们成功调用了 libsotest.so 提供的方法。
package com.me.souser;
import android.os.Bundle;
import android.widget.TextView;
import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import com.me.sotest.JniMethod;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EdgeToEdge.enable(this);
setContentView(R.layout.activity_main);
TextView tv = findViewById(R.id.text);
tv.setText(JniMethod.stringFromJNI());
}
}