Android Studio NDK(C++)

对于部分android开发可能没有使用过NDK,ndk只是工具,我们真正要实现的功能还是需要c/c++来编写我们的实现代码。对于没有使用或学习过c/c++的同学,可能一听到c/c++编码的字眼就会有点头晕,想放弃的想法了。但是其实我们平时在NDK中编写C/C++会用到的语言特有特性很少,或者选择不去使用。完全将其当成java来编写,然后慢慢的会发现其实也就这样嘛。。。

我们首先可以选择使用C++来开始,因为C++相较于C来说更贴近Java,同样能够以面向对象的思想来编写我们的代码。首先我们来创建一个NDK工程。

我们在AS中新建工程:


一直到下一步最后一页


这里让as是否自动为我们设置好前一篇(配置篇)中提的C++11支持。如果作为初学者我们这里可以暂时不去考虑,直接finish创建完成。最后创建出来的的工程目录结构是这样的:


打开MainActivity:


// Used to load the 'native-lib' library on application startup.

static{

System.loadLibrary("native-lib");

}

@Override

protected voidonCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

// Example of a call to a native method

TextView tv = (TextView) findViewById(R.id.sample_text);

tv.setText(stringFromJNI());

}

/*** A native method that is implemented by the 'native-lib' native library,* which is packaged with this application.*/

public nativeStringstringFromJNI();

在这个Activity中像一个abstract方法一样没有方法体

native方法:stringFromJNI()。而在MainActivity中有一个static静态代码块中使用System.loadLibrary加载了一个C/C++的动态库。这样当调用这个native方法的时候就会从动态库中查找对应的C/C++方法。

这个方法在C++中声明为

Java_com_dongnao_hello_1jni_MainActivity_stringFromJNI

我们的native-lib.cpp中全部内容如下:

#include

#include

extern"C"

JNIEXPORTjstringJNICALL

Java_com_dongnao_hello_1jni_MainActivity_stringFromJNI(

JNIEnv*env,

jobject/* this */) {

std::stringhello ="Hello from C++";

returnenv->NewStringUTF(hello.c_str());

可以看到方法声明由extern “C”开始, extern "C"的主要作用就是为了能够正确实现C++代码调用其他C语言代码。加上extern "C"后,会指示编译器这部分代码按C语言的进行编译,而不是C++的。这是由于C++会将函数的参数类型也加到编译后的文件,而C不会。所以如果我们需要在C++中使用C编写的代码、开源库就需要使用extern “C”声明。

然后是JNIEXPORT jstring JNICALL声明,jstring对应了java中的java.lang.String,而在jstring之前的JNIEXPORT则是由jni定义的一个宏(这一部分不感兴趣可以跳过)。JNIEXPORT的定义如下:

#defineJNIIMPORT

#defineJNIEXPORT__attribute__((visibility ("default")))

#defineJNICALL

这个宏是设置属性visibility(可见性),这个属性的作用是防止重复符号的问题。比如说编译的时候指定了-fvisibility=hidden那么没有这个声明的函数会被隐藏,无法让外部调用。而JNICALL宏从上面可以看到是一个空。一般的我们的java native方法的实现会在返回值前后加上这两个宏。当然对于自己app库直接使用而不需要让别的库link(依赖)来说不加这两个宏也可以。

在返回值后是函数名,函数名格式为:Java_包名_类名_方法名。包名的‘.’替换成‘_’,如果包名、类名或方法名本身存在‘_’则用1来区分

如我们的包名是com.dongnao.hello_jni则需要写成:com_dongnao_hello_1jni


我们的这个java native方法是没有任何参数的,但是在jni中我们可以在函数中接受一个JNIEnv与一个jobject。

JNIEnv在c与c++中有不同的定义(这里我们只看C++前面也说了没接触过C/C++的java开发,C++入门更简单)的。C++中定义为_JNIEnv结构体(其实结构体中存在一个JNINativeInterface指针,而C是直接将JNIEnv定义为JNINativeInterface指针)。在C++中需要通过这个结构体去调用JNI函数,如:调用java方法、创建java类对象等,也就是通过JNIEnv来达到与java交互的作用。

而jobject则是当前类的jni对象,如果native方法是static的则jobject对应了MainActivity的class对象,如果不是static则对应了MainActivity的实例对象。

在然后就是方法体中的实现。

嗯,基本的还有java与jni对象的对应关系,这个再我看来不用管,一个是用的多了自然记住了,如果记不住可以利用ide提供的indexer进去查看一眼就明白了,比如我们看jchar:

typedefuint16_tjchar;

typedef__uint16_t    uint16_t;

typedef unsigned short__uint16_t;

所以java当中的char对应了C/C++中的unsigned short(无符号short, -1是有符号,1是无符号)。char在java是两个字节,short在C/C++也是两个字节。而java中的byte占1个字节,对应了jni中的jbyte->signed char。

其次还有关于C/C++调用Java方法时候关于java方法签名的问题。这个也没什么可说的,一张图


如果实在不知道,javap命令查看class文件就行了。比如在as中我们cd到


然后执行:


现在可以让我们开始在android中利用ndk,在C++中编写我们的“java”代码。

9�|.��

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容

  • 什么是JNI? JNI 是java本地开发接口.JNI 是一个协议,这个协议用来沟通java代码和外部的本地代码(...
    a_tomcat阅读 2,810评论 0 54
  • 注:原文地址 1. JNI 概念 1.1 概念 JNI 全称 Java Native Interface,Java...
    cfanr阅读 57,592评论 9 132
  • 一、NDK产生的背景 Android平台从诞生起,就已经支持C、C++开发。众所周知,Android的SDK基于J...
    Ten_Minutes阅读 3,473评论 1 27
  • _ 声明: 对原文格式以及内容做了细微的修改和美化, 主要为了方便阅读和理解 _ 一. 基础 Java Nativ...
    元亨利贞o阅读 5,869评论 0 34
  • 注:原文地址 紧接上篇:Android NDK开发:JNI基础篇 | cfanr,这篇主要介绍 JNI Nativ...
    cfanr阅读 13,038评论 11 56