热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

深入探索NDK与JNI技术的实践应用与学习路径

本文深入探讨了NDK与JNI技术在实际项目中的应用及其学习路径。通过分析工程目录结构和关键代码示例,详细介绍了如何在Android开发中高效利用NDK和JNI,实现高性能计算和跨平台功能。同时,文章还提供了从基础概念到高级实践的系统学习指南,帮助开发者快速掌握这些关键技术。

工程的目录结构如下:


public class MainActivity extends Activity {/** Called when the activity is first created. */@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);String[] argv=new String[]{"mylib","Gao","GaoMatrix"};Natives.libMain(argv);}
}

/*** @author GaoMatrix E-mail:gcquan08@gmail.com* @version Time:2011-8-20*/
public class Natives {static{System.loadLibrary("mylib");}public static native int libMain(String[] argv);private static void onMessage(String text,int level){// System.out.println("Message:"+text+" Level:"+level);Log.d("JNI", "Message:"+text+" Level:"+level);}
}

Android.mk:

LOCAL_PATH:=$(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE:=mylib
LOCAL_SRC_FILES:=mylib.c
LOCAL_LDLIBS := -llog
LOCAL_LDLIBS += -L$(SYSROOT)/usr/lib -lloginclude $(BUILD_SHARED_LIBRARY)

include/Natives.h

/* DO NOT EDIT THIS FILE - it is machine generated */
#include
/* Header for class Natives */#ifndef _Included_Natives
#define _Included_Natives
#ifdef __cplusplus
extern "C" {
#endif
/** Class: Natives* Method: libMain* Signature: ([Ljava/lang/String;)I*/
JNIEXPORT jint JNICALL Java_com_gao_Natives_libMain(JNIEnv *, jclass, jobjectArray);#ifdef __cplusplus
}
#endif
#endif
mylib.c:

#include
#include
#include
#include "include/Natives.h"#include
#define LOG_TAG "JNI"
#define LOGD(a) __android_log_write(ANDROID_LOG_DEBUG,LOG_TAG,a)#define CB_CLASS "com/gao/Natives"/**
* onMessage callback
*/
#define CB_CLASS_MSG_CB "onMessage"
#define CB_CLASS_MSG_SIG "(Ljava/lang/String;I)V"//lib main sub
int lib_main(int argc,char **argv);//Used to get the len of a java Array
const int getArrayLen(JNIEnv* env,jobjectArray jarray);//print str message back to java
void jni_printf(char* format,...);//Global env ref(for callback)
static JavaVM* g_VM;//Global Reference to the native java calss com.gao.Natives.java
static jclass jNativesCls;JNIEXPORT jint JNICALL Java_com_gao_Natives_libMain(JNIEnv *env, jclass cls, jobjectArray jarray)
{//obtain a global ref to the caller class(*env)->GetJavaVM(env,&g_VM);//Extract char **args from java arrayjsize len=getArrayLen(env,jarray);char* args[(int)len];int i;jstring jrow;for(i=0;iGetObjectArrayElement(env,jarray,i);const char* row=(*env)->GetStringUTFChars(env,jrow,0);args[i]=malloc(strlen(row)+1);strcpy(args[i],row);//print argsjni_printf("Main argv[%d]=%s",i,args[i]);//LOGD("From C "+*args[i]);LOGD("From C ");//free java string jrow(*env)->ReleaseStringUTFChars(env,jrow,row);}//Load the com.gao.Natives classjNativesCls=(*env)->FindClass(env,CB_CLASS);if(jNativesCls==0){jni_printf("Unable to find class:%s",CB_CLASS);return -1;}//Invoke the lib main sub.This will loop forener//Program agrs com from Javalib_main(len,args);return 0;
}/**
*Send a string back to Java
*/
jmethodID mSendStr;
static void jni_send_str(const char* text,int level)
{JNIEnv* env;if(!g_VM){printf("I_JNI_NOVM:%s\n",text);return;}(*g_VM)->AttachCurrentThread(g_VM,(void **)&env,NULL);//Load jni.Natives if missingif(!jNativesCls){jNativesCls=(*env)->FindClass(env,CB_CLASS);if(jNativesCls==0){printf("Unable to find class:%s",CB_CLASS);return;}}//Call com.gao.Natives.onMessage(String,int)if(!mSendStr){//Get a ref to the static method:com.gao.Natives.onMessagemSendStr=(*env)->GetStaticMethodID(env,jNativesCls,CB_CLASS_MSG_CB,CB_CLASS_MSG_SIG);}if(mSendStr){(*env)->CallStaticVoidMethod(env,jNativesCls,mSendStr,(*env)->NewStringUTF(env,text),(jint)(level));}else{printf("Unable to find method: %s, signature: %s\n", CB_CLASS_MSG_CB, CB_CLASS_MSG_SIG );}}/**
*Get java array length
*/const int getArrayLen(JNIEnv* env,jobjectArray jarray)
{return (*env)->GetArrayLength(env,jarray);
}/*** Printf into the java layer* does a varargs printf into a temp buffer* and calls jni_sebd_str*/
void jni_printf(char* format,...)
{va_list argptr;static char string[1024];va_start(argptr,format);vsprintf(string,format,argptr);va_end(argptr);jni_send_str(string,0);
}/**
*Library main sub
*/
int lib_main(int argc,char** argv)
{int i;jni_printf("Entering LIB MAIN");for(i=0;i}
运行结果:

08-20 21:50:50.350: DEBUG/JNI(7574): Message:Main argv[0]=mylib Level:0
08-20 21:50:50.350: DEBUG/JNI(7574): From C
08-20 21:50:50.350: DEBUG/JNI(7574): Message:Main argv[1]=Gao Level:0
08-20 21:50:50.350: DEBUG/JNI(7574): From C
08-20 21:50:50.350: DEBUG/JNI(7574): Message:Main argv[2]=GaoMatrix Level:0
08-20 21:50:50.350: DEBUG/JNI(7574): From C
08-20 21:50:50.350: DEBUG/JNI(7574): Message:Entering LIB MAIN Level:0
08-20 21:50:50.350: DEBUG/JNI(7574): Message:Lib Main argv[0]=mylib Level:0
08-20 21:50:50.350: DEBUG/JNI(7574): Message:Lib Main argv[1]=Gao Level:0
08-20 21:50:50.350: DEBUG/JNI(7574): Message:Lib Main argv[2]=GaoMatrix Level:0


推荐阅读
  • 探讨 `org.openide.windows.TopComponent.componentOpened()` 方法的应用及其代码实例分析 ... [详细]
  • 本文将介绍一种扩展的ASP.NET MVC三层架构框架,并通过使用StructureMap实现依赖注入,以降低代码间的耦合度。该方法不仅能够提高代码的可维护性和可测试性,还能增强系统的灵活性和扩展性。通过具体实践案例,详细阐述了如何在实际开发中有效应用这一技术。 ... [详细]
  • Mongoose E11000 错误:集合中出现重复键问题分析与解决 ... [详细]
  • 本文深入探讨了 `ExpressionChangedAfterItHasBeenCheckedError` 错误的原因及其解决方案。通过分析 Angular 的变更检测机制,详细解释了该错误的发生条件,并提供了多种有效的应对策略,帮助开发者在实际开发中避免这一常见问题。 ... [详细]
  • 在Android平台上利用FFmpeg的Swscale组件实现YUV与RGB格式互转
    本文探讨了在Android平台上利用FFmpeg的Swscale组件实现YUV与RGB格式互转的技术细节。通过详细分析Swscale的工作原理和实际应用,展示了如何在Android环境中高效地进行图像格式转换。此外,还介绍了FFmpeg的全平台编译过程,包括x264和fdk-aac的集成,并在Ubuntu系统中配置Nginx和Nginx-RTMP-Module以支持直播推流服务。这些技术的结合为音视频处理提供了强大的支持。 ... [详细]
  • APKAnalyzer(1):命令行操作体验与功能解析
    在对apkChecker进行深入研究后,自然而然地关注到了Android Studio中的APK分析功能。将APK文件导入IDE中,系统会自动解析并展示其中各类文件的详细信息。官方文档提供了详细的命令行工具使用指南,帮助开发者快速上手。本文以一个RecyclerView的Adapter代理开源库为例,探讨了如何利用这些工具进行高效的APK分析。 ... [详细]
  • 在一系列的学习与实践后,Jsoup学习笔记系列即将进入尾声。本文详细介绍了如何使用Jsoup实现从Saz文件到Csv格式的数据解析功能。未来,计划将此功能进一步封装,开发成具有用户界面的独立应用程序,以增强其实用性和便捷性。对于希望深入掌握Jsoup技术的开发者,本文提供了宝贵的参考和实践案例。 ... [详细]
  • 在上篇文章的基础上,本文将继续探讨 Linux 设备驱动中的设备模型与 `devicedriverbus` 机制。在将设备注册到总线之前,需要先创建 `device` 对象。可以通过静态定义 `device` 结构体变量,并调用 `device_register` 函数来完成这一过程。此外,文章还将详细解析设备模型的内部工作机制,以及 `devicedriverbus` 机制如何实现设备与驱动的自动匹配和管理。 ... [详细]
  • 使用 Vue 集成 iScroll 实现移动端表格横向滚动与固定列功能 ... [详细]
  • 本文深入探讨了在React.js中为类组件实现自动绑定的方法与可能性。React.createClass会自动将所有方法绑定到实例,但在React的类组件中,这一功能并非内置。文章分析了如何通过特定技术手段或第三方库来实现类组件方法的自动绑定,以提升开发效率和代码可维护性。 ... [详细]
  • Android数组截取技巧及JNI数组交互在仓库构建中的应用分析
    在Android开发中,数组截取技巧和JNI数组交互在仓库构建中的应用具有重要意义。JNI提供了两种主要的数组处理方法:一是生成原生层数组的副本,二是直接通过数组指针进行操作。在进行字符串处理时,如果需要执行其他复杂操作,可以结合这两种方法以提高效率和灵活性。此外,合理利用这些技术可以显著提升应用程序的性能和稳定性。 ... [详细]
  • 深入解析零拷贝技术(Zerocopy)及其应用优势
    零拷贝技术(Zero-copy)是Netty框架中的一个关键特性,其核心在于减少数据在操作系统内核与用户空间之间的传输次数。通过避免不必要的内存复制操作,零拷贝显著提高了数据传输的效率和性能。本文将深入探讨零拷贝的工作原理及其在实际应用中的优势,包括降低CPU负载、减少内存带宽消耗以及提高系统吞吐量等方面。 ... [详细]
  • 使用React与Ant Design 3.x构建IP地址输入组件
    本文深入探讨了利用React框架结合Ant Design 3.x版本开发IP地址输入组件的方法。通过详细的代码示例,展示了如何高效地创建具备良好用户体验的IP输入框,对于前端开发者而言具有较高的实践指导意义。 ... [详细]
  • 在Linux系统中Nginx环境下SSL证书的安装步骤与WordPress CDN的高级配置指南
    在Linux系统中,Nginx环境下安装SSL证书的具体步骤及WordPress CDN的高级配置指南。首先,安装SSL证书需要准备两个关键配置文件,并建议在操作前备份相关服务器配置文件,以确保数据安全。随后,本文将详细介绍如何在Nginx中正确配置SSL证书,以及如何优化WordPress的CDN设置,提升网站性能和安全性。 ... [详细]
  • 在《数据库技术深度解析:Oracle与SQL优化系列之第五篇》中,我们对Oracle数据库的SQL优化进行了阶段性总结。本文继续探讨了使用UNION ALL替代UNION的优化策略,特别是在可能的情况下,以提高查询性能和效率。此外,还深入分析了这一变更对数据完整性和查询结果的影响,提供了多个实际案例和测试结果,帮助读者更好地理解和应用这些优化技巧。 ... [详细]
author-avatar
大叔丶你好哇塞
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有