闲聊c/c++ 3: 用c/c++混合编程方式为ios/android实现一个自绘日期选择控件(三)

三、Android版本:

android_calendar.jpg

1、ndk开发必要的基础知识:
原本想配套写一下ndk开发方面的基础和步骤,但老实说,这也并非三言两语就能描述清楚的,好在简书上已经有现存的文章了,经过该作者同意,本人就引用一下:@zzyyppqq,thanks

关于开发工具的选择

2014年的时候,基本都是使用eclipse来开发,使用android mk来编译ndk程序。但是目前都是使用AndroidStudio做为开发和编译ndk的工具,因此我们关注AndroidStudio上的实现和编译。

.mk构建系统demo

zzyyppqq-超级简单的Android Studio jni 实现(无需命令行)
通过使用ndk提供的工具来编译ndk程序。
根据上述文档,总结一下开发ndk的流程以及编译过程:

1) public native String getString();在类中用native关键字声明一个成员方法
2) 调用javah程序,自动生成navtie方法对应的.h文件,得到可怕的c/c++函数原型:
   JNIEXPORT jstring JNICALL Java_com_zhangyp_higo_myndk_MyNdk_getString (JNIEnv *, jobject);
3) 在.c或.cpp文件中实现上面javah自动生成的函数
4) 编写mk文件,用于编译生成.so(类linux系统的动态链接库)文件
   包括Application.mk和android.mk这两个mk文件
5) 你可以先调用一下ndk-build clear命令清理一下工程缓存之类的(有时不清理会出现一些问题),然后再调用ndk-build命令用于生成.so文件
6) 在android 类中使用static { System.loadLibrary("MyLibrary"); }方式,将刚才生成的.so加载进来,然后就按照正常的android开发流程进行native函数调用了。

由此可见,Ndk的开发也不是很难,只要记住上面几个步骤,就可以进行简单的ndk开发。

要点:能够被java调用的c/c++库必须是以.so动态链接库方式链接进来的,但是在ios开发中,必须要使用.lib静态链接库方式链入,这是两者很大的区别。
技术在发展,时代在进步。随着AndroidStudio的普及,引入了新的构建系统:gradle系统后,我们可以不用写.mk文件了
要知道,一个稍微复杂一点的ndk项目,要在.mk中撰写很多命令,单单.mk命令参考就有n多页,太可怕了!!
gradle构建系统Demo

zzyyppqq-Android Studio使用gradle-experimental构建NDK工程(无需Android.mk、Application.mk文件)

gradle构建注意点:
1) gradle使用ndk编译,必须要使用:gradle-experimental 插件,这个需要到android相关网站去下载的
2) 一定要注意gradle-experimental的版本号与gradle的对应关系,不能搞混了。曾经我因为没注意这一点,导致掉在坑里两天没出来。太痛苦了(见下图说明)。
3) 一定要按照上文提到的步骤,一步步设置,zzyyppqq的gradle设置流程很清楚,就当武功口诀来使用,否则掉在坑里你也不知道怎么回事。
4) 代码的开发流程和.mk demo差不多,只是不需要编写.mk文件以及调用ndk-build命令了,这是使用gradle-experimental获得的最大好处。

再次强调一下:

gradle-experimental插件与gradle的版本号对应关系图:

对应关系图.png

gradle构建文档参考,请戳这里

使用gradle构建系统后,虽然省掉了.mk文件的撰写,但是很麻烦:
1)需要在java类中用native声明方法
2)需要用Javah生成.h头文件
3)需要在实现.h中的函数时候,很熟悉java中的数据类型和c/c++中的数据类型之间的对应关系
例如JNIEnv,jobject,jstring等,还有其他很多数据类型,可以自己参看ndk开发文档。
4)需要有时调用如此长名字的函数:Java_com_zhangyp_higo_myndk_MyNdk_getString

有没有办法解决上面提到的那些问题呢?

.........我们的猪脚.......SWIG库......出场了......

有了SWIG后,我们就可以正常方式编写C/C++代码,然后自动包装成ndk jni调用,不需要了解android ndk数据类型,不需要javah调用,也不需要native声明,Let's go! go! go! go!

2、SWIG篇章:

SWIG简介:

SWIG全称是Simplified Wrapper and Interface Generator,官方网站是http://www.swig.org/。SWIG是一个开发工具,能够将使用C或者C++编写的软件与其他各种高级编程语言进行嵌入联接。

SWIG目前支持输出的语言列表:
SWIG_Code_Generation.png
SWIG的安装:
1)很简单,官网下载,解压到**最好没有中文字符的**文件夹下
2)由于要使用swig.exe命令行程序,最好设置一下环境变量
3) 在命令行中输入swig -help,出现各种命令参数,说明环境变量设置成功。
Path环境变量.png
AndroidStudio与SWIG配合流程:
1) 严格按照zzyyppqq的文档配置好gradle以及gradle-experimental的参数
2) 在AndroidStudio中按zzyyppqq文档创建jni文件夹
3) 将用c/c++混合编程方式为ios/android实现一个自绘日期选择控件(一)中的
    calendarCore.h和calendarCore.cpp文件复制到jni文件夹下面,如下图:
as_jni_swig.png
4)  编写swig.i文件(接口文件),用于描述如何输出.h文件为java接口,.i表示interface
swig_i.png
5) 编写generate.bat文件用于调用swig.exe自动生成接口文件(很多个,具体我们图示)

interface_gen.png

双击运行bat前后效果如下:

bat前后对比图.png
 6) swig转换的流程分析:
流程.png
7) c/c++中的struct和class会自动生成java对应的类,并自动添加(如果需要的话)get/set函数:请查看CGPoint.java SCalendar.java等源码

8) c/c++中的输出参数,例如void calendar_get_year_month(SCalendar* calendar,int* year,int* month);
int* year 和 int* month是传地址方式,将结果传出来,对于java来说,必须要装箱(boxing)以及拆箱(unboxing)
将int传值方式变为传引用方式,因此自动生成了SWIG_TYPE_p_int.java类,用于将值类型变为引用类型
到此为止,SWIG的使命已经完成了,接下来纯粹属于Android java的控件开发,其中会经常调用上面分析过的由SWIG自动生成的Java类。

3、 Android版Calendar的源码:
源码不再分析,实现细节可以参考
用c/c++混合编程方式为ios/android实现一个自绘日期选择控件-IOS实现
Android版所有的源码请狠狠地戳这里
https://github.com/jackyblf/

4、 到此,c/c++结合ios/android原生开发的文章结束了,花了两个礼拜,将近13000字。也算是呕心沥血吧。 如果觉得有用,请关注我一下,谢谢

说明:
关于一些原创的文章,除非是一些第三方经典源码分析,否则我一定会提供相应的demo。

Next:

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

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 172,195评论 25 707
  • Android游戏开发实践(1)之NDK与JNI开发02 承接上篇Android游戏开发实践(1)之NDK与JNI...
    AlphaGL阅读 3,754评论 0 24
  • demo链接在文末。 在Android Studio中有3种方法生成so文件。 最初的时候,我曾经使用过Visua...
    梧叶已秋声阅读 33,735评论 5 26
  • 行走的画报 花帽 分衩长条纹衫 焦蓝阔腿裤 街头 束腰大褂 白稠飘裙 舒适毛衫 薄绿长裙 像水纹,细长腿若现 妩媚...
    _觅小金桔阅读 263评论 0 2
  • 儿子个头已经比我高不少了。这是和儿子打球的时候媳看着我们爷俩抢球的时候和我说的,我的身高是184公分。现在这小子正...
    微笑的大富阅读 209评论 0 0