如何在Android Studio中生成.so文件并在其他Android应用中调用
嘿,作为刚入坑Android NDK的新手,你已经搞定了带C++支持的项目,这步超棒!接下来我一步步带你搞定生成.so文件,再在其他应用里调用它:
第一步:生成.so文件
你的项目是用Android Studio 3.0.1创建的带C++支持的项目,默认应该用CMake构建,咱们从配置到编译一步步来:
确认NDK路径配置
先打开Android Studio的File > Project Structure > SDK Location,检查Android NDK location是否已经设置。如果没装NDK,直接点旁边的Download按钮,选适配你Studio版本的NDK(比如r16b,和3.0.1兼容性较好)下载安装即可。检查CMakeLists.txt配置
打开app模块下的CMakeLists.txt,确保里面有生成动态库的配置,核心是SHARED关键字(生成动态库.so,静态库是STATIC),示例配置如下:
cmake_minimum_required(VERSION 3.4.1) # 定义你的C++库名称(比如叫prime-checker),指定为SHARED动态库 add_library( prime-checker SHARED src/main/cpp/your_prime_check_file.cpp) # 替换成你实际的C++文件路径 # 链接Android系统的log库(如果你的C++代码里用到log的话) find_library( log-lib log) # 把你的库和系统库链接起来 target_link_libraries( prime-checker ${log-lib})
- 编译生成.so文件
点击Android Studio右上角的Build > Make Project(或者直接点工具栏的Make图标),等待编译完成。
编译后的.so文件会存放在app/build/intermediates/cmake/debug/obj/目录下,不同CPU架构(比如armeabi-v7a、arm64-v8a、x86)对应不同的子文件夹,每个文件夹里都有libprime-checker.so文件。
如果需要生成release版本的.so,先切换到release变体(Build Variants面板),再执行Make Project,或者用Build > Generate Signed Bundle/APK生成签名包,对应的release版.so在app/build/intermediates/cmake/release/obj/目录下。
第二步:在其他Android应用中调用.so文件
拿到.so文件后,咱们在新应用里集成调用:
复制.so文件到新项目
在你的新Android项目中,创建src/main/jniLibs目录(如果没有的话),然后把刚才生成的各个架构的文件夹(比如armeabi-v7a)整个复制到jniLibs目录下,最终结构应该是:src/main/jniLibs/ armeabi-v7a/libprime-checker.so arm64-v8a/libprime-checker.so x86/libprime-checker.so如果你只需要适配特定架构,只复制对应的文件夹就行,能减小APK体积。
创建JNI接口类
在新项目里创建一个Java类,用来声明native方法,注意要加载.so库,并且方法签名要和C++里的JNI方法完全匹配:
package com.yournewapp.package; // 换成你新项目的包名 public class PrimeChecker { // 加载.so库,库名是CMake里定义的"prime-checker",去掉前缀lib和后缀.so static { System.loadLibrary("prime-checker"); } // 声明native方法,参数和返回值要和C++里的方法一致 public native boolean isPrime(int number); }
- 在Activity中调用native方法
现在就可以像调用普通Java方法一样使用这个native方法了,示例代码:
import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import androidx.appcompat.app.AppCompatActivity; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); EditText inputEt = findViewById(R.id.input_number); Button checkBtn = findViewById(R.id.check_btn); TextView resultTv = findViewById(R.id.result_tv); checkBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { try { int num = Integer.parseInt(inputEt.getText().toString()); PrimeChecker checker = new PrimeChecker(); boolean result = checker.isPrime(num); resultTv.setText(result ? num + "是质数" : num + "不是质数"); } catch (NumberFormatException e) { resultTv.setText("请输入有效数字"); } } }); } }
- 关键注意点
- 方法签名必须完全匹配:C里的JNI方法名格式是
Java_包名_类名_方法名,包名里的.要换成_。比如你把native方法放在刚才的PrimeChecker类里,C里的方法应该是:
- 方法签名必须完全匹配:C里的JNI方法名格式是
#include <jni.h> extern "C" JNIEXPORT jboolean JNICALL Java_com_yournewapp_package_PrimeChecker_isPrime(JNIEnv* env, jobject thiz, jint number) { // 你的质数判断逻辑,和原项目里的一致 if (number <= 1) return JNI_FALSE; for (int i = 2; i * i <= number; ++i) { if (number % i == 0) return JNI_FALSE; } return JNI_TRUE; }
- 确保新项目的
minSdkVersion和原项目兼容,不然可能出现加载库失败的情况。 - 如果运行时出现
UnsatisfiedLinkError,先检查库名是否正确、方法签名是否匹配、.so文件的架构是否和测试设备匹配。
内容的提问来源于stack exchange,提问作者PPD




