热门标签 | 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


推荐阅读
  • 二维码的实现与应用
    本文介绍了二维码的基本概念、分类及其优缺点,并详细描述了如何使用Java编程语言结合第三方库(如ZXing和qrcode.jar)来实现二维码的生成与解析。 ... [详细]
  • importjava.io.*;importjava.util.*;publicclass五子棋游戏{staticintm1;staticintn1;staticfinalintS ... [详细]
  • 本文探讨了如何在游戏启动画面中移除广告,特别是在游戏数据加载期间(大约5-6秒)广告会短暂显示的问题。通过调整XML布局和代码逻辑,可以实现广告的延迟加载或完全移除。 ... [详细]
  • 作为一名Android应用开发新手,我在尝试将MediaPlayer处理逻辑从MainActivity分离到另一个类时遇到了问题。尽管搜索了很长时间,但仍未找到满意的解决方案。 ... [详细]
  • Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面Android异步处理二:使用AsyncTask异步更新UI界面Android异步处理三:Handler+Loope ... [详细]
  • 本文深入探讨了Go语言中的接口型函数,通过实例分析其灵活性和强大功能,帮助开发者更好地理解和运用这一特性。 ... [详细]
  • 本文介绍了如何通过C#语言调用动态链接库(DLL)中的函数来实现IC卡的基本操作,包括初始化设备、设置密码模式、获取设备状态等,并详细展示了将TextBox中的数据写入IC卡的具体实现方法。 ... [详细]
  • 问题场景用Java进行web开发过程当中,当遇到很多很多个字段的实体时,最苦恼的莫过于编辑字段的查看和修改界面,发现2个页面存在很多重复信息,能不能写一遍?有没有轮子用都不如自己造。解决方式笔者根据自 ... [详细]
  • Java中如何判断一个对象是否为Long类型
    本文介绍了一种在Java中判断对象是否属于Long类型的方法,通过定义一个特定的方法来实现这一功能,该方法能够准确地识别并返回结果。 ... [详细]
  • 数据类型--char一、char1.1char占用2个字节char取值范围:【0~65535】char采用unicode编码方式char类型的字面量用单引号括起来char可以存储一 ... [详细]
  • android开发分享荐                                                         Android思维导图布局:效果展示及使用方法
    思维导图布局的前身是树形布局,对树形布局基本使用还不太了解的朋友可以先看看我写的树形布局系列教程,了解了树形布局的使用方法后再来阅读本文章。先睹为快来看看效果吧,横向效果如下:纵向 ... [详细]
  • 本文详细介绍了如何在Android应用中实现重复报警功能。示例代码可在以下路径找到:https://developer.android.com/samples/RepeatingAlarm/index.html。首先,我们将从Manifest文件开始分析。 ... [详细]
  • 本文介绍了如何使用 Gesture Detector 和 overridePendingTransition 方法来实现滑动界面和过渡动画。 ... [详细]
  • 使用TabActivity实现Android顶部选项卡功能
    本文介绍如何通过继承TabActivity来创建Android应用中的顶部选项卡。通过简单的步骤,您可以轻松地添加多个选项卡,并实现基本的界面切换功能。 ... [详细]
  • 在尝试使用 Android 发送 SOAP 请求时遇到错误,服务器返回 '无法处理请求' 的信息,并指出某个值不能为 null。本文探讨了可能的原因及解决方案。 ... [详细]
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社区 版权所有