Android 如何使用 so 库

851 阅读1分钟

前言

Android 开发中难免会使用到 jni,实践中虽然简单,但也还是有不少坑点。上一节我们讲了如何生成 so 文件,接下来我们继续看看怎么在其他项目里使用我们生成的 so 库。

Android 如何生成 so 库 - 掘金 (juejin.cn)

新建项目

新建了一个 Empty Android 项目 SoUser,包名为com.me.souser。 在项目的 app 目录下新建 libs 文件夹,把我们的 so 文件拷贝进去,arm64-v8a 这个文件目录是因为我测试用的手机 cpu 架构为 arm64-v8a。

image.png

然后修改 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());
    }
}