牙叔教程 简单易懂
使用场景
复用c语言, 使用so文件
环境
软件名字 |
软件版本 |
autojs |
8.8.12-0 |
android studio |
4.1.2 |
java |
1.8.0_131 |
以上环境配置, 百度很多,不赘述了
android studio生成so文件的流程图
android studio生成so文件的步骤讲解
1. 新建java类
// 1. 加载so文件 // 2. 声明本地方法 package com.yashu.usec; public class Student { static { System.loadLibrary("soname"); } public static native int doMathSum(int a,int b); }
2. 生成头文件
cd到路径 app/src/main/java 输入命令 javah -jni com.yashu.usec.Student 会生成头文件 app/src/main/java/com_yashu_usec_Student.h
3. 编写c方法
// 路径: app/src/main/jni/xiaoqiang.c #include "com_yashu_usec_Student.h" JNIEXPORT jint JNICALL Java_com_yashu_usec_Student_doMathSum (JNIEnv * env, jclass obj, jint a, jint b){ return a+b; }
4. 编写 Android.mk 和 Application.mk
// 路径 app/src/main/jni/Android.mk LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := soname LOCAL_SRC_FILES := xiaoqiang.c include $(BUILD_SHARED_LIBRARY)
// 路径 app/src/main/jni/Application.mk APP_PLATFORM := android-26 APP_ALLOW_MISSING_DEPS=true APP_ABI := arm64-v8a, armeabi-v7a, x86, x86_64
5. 复制头文件到 app/src/main/jni/com_yashu_usec_Student.h
6. 生成so文件
cd到路径 app/src/main/jni 命令行中输入 ndk-build 生成的so所在文件夹 app/src/main/libs
7. make project, 一共四个步骤
// 1. app的build.gradle中添加ndk配置 android { compileSdkVersion 30 buildToolsVersion "30.0.3" externalNativeBuild { ndkBuild { // Provides a relative path to your ndkBuild script. path file("src/main/jni/Android.mk") } } defaultConfig { ... } }
2. 点击菜单build/make project
3. 提取dex, 路径为 app\build\intermediates\dex\debug\mergeProjectDexDebug\classes.dex
4. 提取so, 我的手机是armeabi-v7a
5. 剩下的要在autojs测试
autojs调用so文件, 执行c函数
// 复制so文件到指定目录, 不需要runtime.loadDex let soPath = "/sdcard/Android/data/com.tencent.mobileqq/Tencent/QQfile_recv/libsoname777.so"; let dexPath = "/sdcard/Android/data/com.tencent.mobileqq/Tencent/QQfile_recv/classes777.dex"; var ctx = context; var cwd = files.cwd(); var jniPath = ctx.getDir("libs", android.app.Activity.MODE_PRIVATE); log("jniPath = " + jniPath); var dirpath = ctx.getDir("dex", android.app.Activity.MODE_PRIVATE).getAbsolutePath(); log("dirpath = " + dirpath); copy(soPath, new java.io.File(jniPath, "libsoname.so").getAbsolutePath()); var dcl = new Packages.dalvik.system.DexClassLoader( dexPath, dirpath, jniPath, java.lang.ClassLoader.getSystemClassLoader() ); var cls = dcl.loadClass("com.yashu.usec.Student"); var api = cls.newInstance(); let result = api.doMathSum(1, 2); log(result); function copy(f, t) { var fip = new java.io.FileInputStream(f).getChannel(); var fop = new java.io.FileOutputStream(t).getChannel(); fip.transferTo(0, fip.size(), fop); fip.close(); fop.close(); }
支持的cpu架构
let r = android.os.Build.CPU_ABI; log(r); // armeabi-v7a let abis = android.os.Build.SUPPORTED_ABIS; log(abis); // [arm64-v8a, armeabi-v7a, armeabi]
参考文章
- android studio ndk编译的两种方式(ndk-build和cmake)配置
- NDK笔记(二)-在Android Studio中使用ndk-build
- Android NDK系列一(ndk在android studio基本编译配置 ndk-build 和 cmake)
- android studio ndk环境搭建(Android.mk方式)
- Android Studio NDK开发之一(Java调用C的方法)
声明
部分内容来自网络
本教程仅用于学习, 禁止用于其他用途