Android studio如何利用Android.mk编译生成多个so文件
来源:互联网 发布:玻璃排班优化软件 编辑:程序博客网 时间:2024/06/07 04:43
我们这次不用gradle 去生成SO文件,改用Android.mk 去编译。
一共分为2步:
1.在Java中编写要调用的静态方法和需要加载的库,并生成头文件。
2.配置gradle
3.配置Android.mk文件和application.mk文件
下面一步步的走:
首先需要在Java类中声明要调用的方法,以及要加载的库,我们在包下新建一个jniUtil类,如下所示
public class jniUtil {//要加载的库,生成的库格式为:lib+库名.so static{ System.loadLibrary("hello-jni"); }//要调用的本地方法,在c文件中该方法名称格式为:java_包名_类名_方法名 public static native String stringFromJNI();}
注意:在编译时该类中不能有汉字,包括注释,否则会出现编码GBK的不可映射字符错误。
接下来就是利用external Tools生成头文件.h,这里可参考点击打开链接
然后就会在main目录下生成Jni文件夹,并且包含.h文件。下面就是编写C文件,或者可以拷贝已经写好的C文件放置在该jni文件夹中.
2.配置gradle
我们这里不用gradle 去编译,而是只让他去加载已经生成的so库,改用android.mk 去编译(稍后配置android.mk)
在app的build.gradle 下的android 标签下添加:
sourceSets { main { jni.srcDirs = []//禁止gradle 自动编译,使用已经编译好的So库 jniLibs.srcDirs = ['src/main/jniLibs','libs']//指向要使用的库文件//的路径,前边的是自己项目的,后边的是第三方的so } }
从上面可以看出,我们生成的库是放在
src/main/jniLibs
目录下面的,那么这个是如何配置呢?还是在该gradle下面配置ndk的编译脚本,注意放在android标签外面:
tasks.withType(JavaCompile) { compileTask -> compileTask.dependsOn CopyToJniLibs}task ndkBuild(type: Exec, description: 'Compile JNI source via NDK') { Properties properties = new Properties() properties.load(project.rootProject.file('local.properties').newDataInputStream()) def ndkDir = properties.getProperty('ndk.dir') commandLine "$ndkDir/ndk-build.cmd", "NDK_PROJECT_PATH=$projectDir.absolutePath\\build", "APP_BUILD_SCRIPT=$projectDir.absolutePath\\src\\main\\jni\\Android.mk", "NDK_APPLICATION_MK=$projectDir.absolutePath\\src\\main\\jni\\Application.mk" //你自己的mk文件目录}
在ndkbuild完成后把生成的so文件复制到jniLibs,这里和上面配置的加载so文件路径要一致哦
task CopyToJniLibs(type: Copy, dependsOn: 'ndkBuild', description: 'copy the native libs to jniLibs') { from fileTree(dir: file(buildDir.absolutePath + '/libs'), include: '**/*.so') into file('src/main/jniLibs')}
新建Android.mk和application.mk,这里我把Android.mk和application.mk放在jni文件夹下了,具体可以自己修改。默认生成的SO文件会在build下面的libs中,我们拷贝出来放到src/main/jniLibs下面。
3.配置Android.mk和Application.mk
先说Application.mk,APP_ABI := all代表生成所有平台的库文件。
也可以修改为APP_ABI := armeabi armeabi-v7a x86,代表生成这三个平台的so文件。
重点说下Android.mk.先看代码:
LOCAL_PATH := $(call my-dir) LOCAL_LDLIBS := -llog LOCAL_CPP_FLAGS := -fno-rtti #声明一个预编译库的模块:共享库include $(CLEAR_VARS) LOCAL_MODULE := jniUtilLOCAL_MODULE_FILENAME:=libjniUtilLOCAL_SRC_FILES :=jniUtil.c util.cinclude $(BUILD_SHARED_LIBRARY)
解释一下各参数:
1.LOCAL_PATH := $(call my-dir) 指向当前目录的地址,包含该.mk
2.LOCAL_LDLIBS := -llog
链接的库不产生依赖关系,一般用于不需要重新编译的库,如库不存在,则会报错找不到。且貌似只能链接那些存在于系统目录下本模块需要连接的库。如果某一个库既有动态库又有静态库,那么在默认情况下是链接的动态库而非静态库。
如:LOCAL_LDLIBS += -lm –lz –lc -lcutils –lutils –llog …
如果你的Android.mk文件中只有这么一行,那么将会采用动态链接。
3.LOCAL_CPP_FLAGS := -fno-rtti 缺省情况下都是用-fno-rtti来编译C++代码
4.include $(CLEAR_VARS) 清理掉所有以LOCAL_开头的内容,这句话是必须的,因为如果所有的变量都是全局的,所有的可控的编译文件都需要在一个单独的GNU中被解析并执行。
5.LOCAL_MODULE :=hello-jni,
调用的库名,用来区分android.mk中的每一个模块。文件名必须是唯一的,不能有空格。注意,这里编译器会为你自动加上一些前缀lib和后缀.so,来保证文件是一致的。
6.LOCAL_SRC_FILES :=jniUtil.c util.c
变量必须包含一个C、C++或者java源文件的列表,这些会被编译并聚合到一个模块中,文件之间可以用空格或Tab键进行分割,换行请用"\"
7.include $(BUILD_SHARED_LIBRARY) 来生成一个动态库libhello-jni.so
如果要生成多个库文件,则在下面可以再加入
include $(CLEAR_VARS)LOCAL_MODULE := UtilLOCAL_MODULE_FILENAME:=libUtilLOCAL_SRC_FILES := util.cinclude $(BUILD_SHARED_LIBRARY)那么则可以生成libUtil.so文件
8.rebuild 一下,可以查看src/main/jniLibs目录下生成了so文件.至此编译完成.
后话:
要记得在gradle.properties文件中加入
android.useDeprecatedNdk=true否则会报错!
0 0
- Android studio如何利用Android.mk编译生成多个so文件
- Android Studio 生成.so文件及 Android.mk文件解析
- Android Studio jni编译生成so文件
- android studio 编译C生成.so文件
- android studio编译c生成.so文件
- android studio 编译C生成.so文件
- Android studio下配置ndk以及利用gradle编译生成SO文件
- Android Studio使用自定义的Android.mk文件编译第三方so库
- Android Studio 使用Android.mk文件控制编译so,不用AS自动的
- android studio编译.so文件
- 重温android studio jni编译生成so文件
- android studio 中编译C生成.so文件
- 关于android studio进行NDK编译生成.so文件
- Android.mk 文件,多个mk文件
- android NDK编译多个so文件
- android NDK编译多个so文件
- android NDK编译多个so文件
- android NDK编译多个so文件
- java对象输入输出流
- 从C转换到到Delphi运算符
- 拆散组合思路求解期望,方差
- 面试总结-----工程化软件项目开发的流程、步骤
- 【NOIp模拟】【二分图or并查集】GoToandPlay
- Android studio如何利用Android.mk编译生成多个so文件
- mysql语句
- 深入uCOS中全局变量的使用详解
- AOJ.800 热身之开关灯
- MySQL创建触发器(简略版)
- Unable to instantiate application com.android.tools.fd.runtime.BootstrapApplication
- php数组去重
- java获取项目中文件路径
- 使用DatePicker以及TimePicker显示当前日期和时间