Android JNI编程 与 NDK开发(二) AS 2.2以上NDK开发 ndk-build 篇
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Android JNI编程 与 NDK开发(二) AS 2.2以上NDK开发 ndk-build 篇,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含4660字,纯文字阅读大概需要7分钟。
内容图文
![Android JNI编程 与 NDK开发(二) AS 2.2以上NDK开发 ndk-build 篇](/upload/InfoBanner/zyjiaocheng/840/58897f41601c4f77b1a060e2521cf94e.jpg)
这篇我们结合一个简单的例子(c计算器)来讲讲在AS怎么用ndk-build来完成JNI。
(PS:此时作者的AS版本为2.3,改动不大)
首先我们要在AS中集成两个外部工具(External Tools)——Javah和ndk-build。(请注意你应该已经在SDK Tools勾选NDK了)
javah 生成实现本地方法所需的 C 头文件,简单讲,他会给你指定的java类中native方法自动生成对应c中的头文件(.h文件)。
ndk-build 就是我们的主角,是一个新的、小巧的shell脚本,用来简化源码编译。
我们可以在File->setting->Tools中,找到这个选项,然后点击绿色“+”按钮。
第一个工具javah:
-
Name:javah-jni
名称,你可以随意命名
-
Program:$JDKPath$/bin/javah
javah所在的路径,$JDKPath$代表在环境变量中配置的JDK路径。
-
Parameters:-jni -encoding UTF-8 -d $ModuleFileDir$\src\main\jni $FileClass$
命令参数:
-
-jni代表生成JNI样式的标头文件,文件名为当前包名+类名($FileClass$)
-
-encoding代表编码格式为UTF-8
-
-d代表指定头文件的输出路径为jni目录($ModuleFileDir$\src\main\jni )
-
-
Working directory:$ModuleFileDir$\src\main\java
工作目录,$ModuleFileDir$为当前module的路径。
第二个工具ndk-build:
Name:ndk-build
Program:这里需要的是你自己的NDK路径(在File->Project Structure中的Android NDK Location可以找到),因为不同的版本之间有差异,所以记得定位到 ndk-build.cmd
Working directory:$ModuleFileDir$\src\main\
到这里需要的两个工具都有了,接下来就是怎么用它们了。
第一,我们要有一个文件夹放我们的原生代码
然后在src/main下就多了一个名为 jni 的目录
第二,头文件的生成
右键点击包含native方法的类(这里我们直接在MainActivity里新增一个就行,顺便调用它。)
修改MainActivity
public class MainActivity extends AppCompatActivity {
// 加载native-lib,不加lib前缀
static {
System.loadLibrary("native-lib");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView textView = (TextView)findViewById(R.id.tx);
//对,作者很懒,这里写死。
textView.setText(stringFromJNI() + calFromJNI(11, 22));
}
/**
* native-lib中的原生方法
*/
//从c中返回字符串的native方法
public native String stringFromJNI();、
//java传参给c并返回int值得native方法
public native int calFromJNI(int num1, int num2);
}
然后在左边面板中右键点击MainActivity,External Tools->javah-jni,
不需眨眼时间就出来了。
于是我们可以在src/main/jni下面找到生成出来的头文件xxx_xxx_xxx_MainActivity.h,当中代码是这样的。
可以看到我们的两个native方法stringFromJNI跟calFromJNI在这里的声明。
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_example_whitecrow_myapplication_MainActivity */
#ifndef _Included_com_example_whitecrow_myapplication_MainActivity
#define _Included_com_example_whitecrow_myapplication_MainActivity
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_example_whitecrow_myapplication_MainActivity
* Method: stringFromJNI
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_example_whitecrow_myapplication_MainActivity_stringFromJNI
(JNIEnv *, jobject);
/*
* Class: com_example_whitecrow_myapplication_MainActivity
* Method: calFromJNI
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_com_example_whitecrow_myapplication_MainActivity_calFromJNI
(JNIEnv *, jobject, jint, jint);
#ifdef __cplusplus
}
#endif
#endif
第三,正式在c中实现这些native方法。
在jni文件夹下新建一个 c/c++ Source File,代码如下:
#include "com_example_whitecrow_myapplication_MainActivity.h"
//嘿,注意,这是我的头文件名,你应该替换成你的头文件名
//stringFromJNI的具体实现,方法名是通过 Java_包名_类名_方法名 的方式命名的。
JNIEXPORT jstring JNICALL Java_com_example_whitecrow_myapplication_MainActivity_stringFromJNI
(JNIEnv *env, jobject) {
return env->NewStringUTF("11 + 22 =");
}
//calFromJNI的具体实现
JNIEXPORT jint JNICALL Java_com_example_whitecrow_myapplication_MainActivity_calFromJNI
(JNIEnv *, jobject, jint n1, jint n2) {
jint result = n1 + n2;
return result;
}
第四,在jni目录下创建Android.mk和Application.mk配置文件
Android.mk
# 当前路径
LOCAL_PATH := $(call my-dir)
# 清除LOCAL_XXX变量
include $(CLEAR_VARS)
# 原生库名称
LOCAL_MODULE := native-lib
# 原生代码文件
LOCAL_SRC_FILES =: native-lib.cpp
# 编译动态库
include $(BUILD_SHARED_LIBRARY)
在app的build.gradle文件中关联Android.mk:
android {
...
externalNativeBuild {
ndkBuild {
path 'src/main/jni/Android.mk'
}
}
}
Application.mk
# 原生库名称
APP_MODULES := native-lib
# 指定机器指令集
APP_ABI := armeabi armeabi-v7a arm64-v8a x86 x86_64 mips mips64
第五,好了,我们可以编译运行一下了
右键jni,External Tools -> ndk_build,这个操作会在main目录下生成libs和obj目录,编译出的so文件就在libs目录下:
Perfect,一切顺利。
这是个简单无比的c实现的对两个参数相加的简单例子,但是可以完成传参、调用、返回,已经足以实现许多功能了。
你可以顺着这个例子的思路发挥,无非就是新增native方法,然后再把类用 javah 工具生成头文件,接着在native-lib.cpp中实现这个方法即可。
内容总结
以上是互联网集市为您收集整理的Android JNI编程 与 NDK开发(二) AS 2.2以上NDK开发 ndk-build 篇全部内容,希望文章能够帮你解决Android JNI编程 与 NDK开发(二) AS 2.2以上NDK开发 ndk-build 篇所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。