Android NDK 学习之接受Java传入的Int数组
2014-12-03 12:17 雪夜&流星 阅读(276) 评论(0) 编辑 收藏 举报本博客主要是在Ubuntu 下开发,且默认你已经安装了Eclipse,Android SDK, Android NDK, CDT插件。
在Eclipse中添加配置NDK,路径如下Eclipse->Window->Preferences->Android->NDK ,选择NDK的路径,然后Apply即可。
新建一个名为AndroidJNI_IntArray的Android工程,新建一个jni的文件夹,其目录下文件树列表如下:
├── jni
│ ├── Android.mk
│ ├── Application.mk
│ └── intarray
│ ├── Android.mk
│ ├── intarray_jni.c
│ └── logger.h
jni/Application.mk文件内容如下:
APP_ABI := all
jni/Android.mk,主要用来指定顺序执行所有子文件夹下面的makefile文件,内容如下:
include $(call all-subdir-makefiles)
jni/intarray/Android.mk,主要用来指定需要编译出的动态库的名称,以及需要编译的源文件,内容如下:
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := intarray_jni LOCAL_SRC_FILES := intarray_jni.c LOCAL_LDLIBS := -llog include $(BUILD_SHARED_LIBRARY)
jni/intarray/logger.h 主要用来在JNI层打印日志,内容如下:
#include <jni.h> #include <android/log.h> /** * 定义log标签 */ #define TAG "jni_logger" /** * 定义info信息 */ #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__) /** * 定义debug信息 */ #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__) /** * 定义error信息 */ #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__)
jni/intarray/intarray_jni.c,主要用来注册绑定java函数和native函数,以及java函数在c中相应函数的具体实现, 内容如下:
#include "logger.h" #ifndef NULL #define NULL ((void *) 0) #endif /** * 获取数组的大小 */ #define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0]))) /** * 指定要注册的类,对应的完整的java类名 */ #define JNIREG_CLASS "com/clarck/jni/MainActivity" /** * 返回数组元素的值的和 */ JNIEXPORT jint JNICALL native_sumArray(JNIEnv *env, jobject obj, jintArray arr) { jint *carr; jint i, sum = 0; carr = (*env)->GetIntArrayElements(env, arr, NULL); if (carr == NULL) { return 0; } for (i = 0; i < 10; i++) { sum += carr[i]; } (*env)->ReleaseIntArrayElements(env, arr, carr, 0); return sum; } /** * Java和JNI函数绑定 */ static JNINativeMethod method_table[] = { { "sumArray", "([I)I", (void*)native_sumArray }, }; /** * 注册native方法到java中 */ static int registerNativeMethods(JNIEnv* env, const char* className, JNINativeMethod* gMethods, int numMethods) { jclass clazz; clazz = (*env)->FindClass(env, className); if (clazz == NULL) { return JNI_FALSE; } if ((*env)->RegisterNatives(env, clazz, gMethods, numMethods) < 0) { return JNI_FALSE; } return JNI_TRUE; } /** * 调用注册方法 */ int register_ndk_load(JNIEnv* env) { return registerNativeMethods(env, JNIREG_CLASS, method_table, NELEM(method_table)); } JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) { JNIEnv* env = NULL; jint result = -1; if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_4) != JNI_OK) { return result; } register_ndk_load(env); //返回jni的版本 return JNI_VERSION_1_4; }
接着在Project中右键Android Tools->Add Native Support,最后java层调用如下:
package com.clarck.jni; import android.app.Activity; import android.os.Bundle; import android.util.Log; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); int arr[] = new int[10]; for (int i = 0; i < 10; i++) { arr[i] = i; } int sum = sumArray(arr); Log.d("Test", "sum : " + sum); } public native int sumArray(int[] arr); static { System.loadLibrary("intarray_jni"); } }
最后执行Ctrl+B执行编译,运行即可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本