目录
4.编写Android.mk和Application.mk文件
现在的Android Studio打包so文件有两种方式,第一种是ndk-build编译项目,还有一种用CMake脚本构建项目,在这里主要介绍ndk-build的编译过程,并记录自己的调试过程。
1.下载安装ndk
在下载ndk之前要安装好jdk和sdk并配置好环境,这里就不说了,自己之前是配好了的:
为了编译和调试,需要安装ndk组件, Android 原生开发工具包 (NDK):这套工具集允许您为 Android 使用 C 和 C++ 代码,并提供众多平台库,让您可以管理原生 Activity 和访问物理设备组件,例如传感器和触摸输入。
安装过程:在打开的项目中,从菜单栏选择 File > Settings >搜索 sdk > 选择SDK tools
点击Apply,等Finish后点击ok。
2.ndk环境配置
上述方式下载的ndk一般都自动放在sdk目录下面,打开你的项目的project structure配置ndk:
由于我之前Android NDK location无法配置无法选中修改 也无法下载 Download都是灰的点不了但明明已经下载了ndk并显示完成。实际 File —— Project Structure SDK location 依然是没有配置NDK路径。然后我就参照网上的博客手动配置了一下ndk环境:
在local.properties 中手动添加本地ndk.dir路径:
然后再打开project structure就会自动出现上述情况了。(我后来改成了sdk下的这一个路径:
ndk.dir=D\:\\SDK\\ndk-bundle
)
为最外层工程目录下的gradle.properties的文件末尾加上android.useDeprecatedNdk=true这段代码(如果没有这个目录,自己新建一个),如下图所示:
上面我们把环境给配置好了,下面我们就可以写Java和C代码了
添加环境变量:
3.java和c代码编写
首先新建一个java类JNIUtils.java,代码如下:我是创建在(如图)文件下的
public class JNIUtils {
static {
System.loadLibrary("native-jni");
}
public native String stringFromJNI();
}
然后Make Project:
完成后会在工程目录 \app\build\intermediates\javac\debug\classes\com\example\maze 下面看到自己编译后的classes文件JNIUtils.class:注意是在build\intermediates\javac下面,我之前找了好久它在哪里。
用javah命令生成头文件:
打开终端命令Terminal:输入命令:javah -d jni -classpath 自己编译后的class文件的绝对路径
例如我的:
按回车之后就会在main目录下生成jni文件夹,同时生成.h文件,如下图所示:
现在我们在jni目录下新建一个 native-lib.c 的 c 文件,内容如下:
//
// Created by Wang丶99WEI on 2021/12/16.
//
#include "com_example_maze_JNIUtils.h"
/**
* 上边的引用标签一定是.h的文件名家后缀,方法名一定要和.h文件中的方法名称一样
*/
JNIEXPORT jstring JNICALL Java_com_example_maze_JNIUtils_stringFromJNI
(JNIEnv *env, jobject ojb){
return (*env) -> NewStringUTF(env,"Hello, I'm from jni");
}
4.编写Android.mk和Application.mk文件
接着在jni文件夹下新建Android.mk和Application.mk文件。
Android.mk:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := native-jni
LOCAL_SRC_FILES := native-lib.c
include $(BUILD_SHARED_LIBRARY)
Application.mk:
APP_ABI := all
然后在终端进入到jni目录,输入指令 ndk-build,就会生成相应的so文件。
然后需要设定一下jniLibs的文件路径,在app的build.gradle文件中Android{}内添加如下代码,其中'src/main/libs'为libnative-jni.so文件所在的路径
sourceSets {
main() {
jniLibs.srcDirs = ['src/main/libs']
jni.srcDirs = [] //屏蔽掉默认的jni编译生成过程
}
}
5.结果测试
最后在我们来测试一下,只需要在MainActivity中调用一下C就可以了,代码如下:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView textView = (TextView) findViewById(R.id.text);
textView.setText(new JNIUtils().stringFromJNI());
}
}
然后运行: