JNI开发系列阅读

JNI与底层调用1:http://blog.csdn.net/axi295309066/article/details/60758515
JNI与底层调用2:http://blog.csdn.net/axi295309066/article/details/60778076
C/C++在Android开发中的应用:http://blog.csdn.net/axi295309066/article/details/60954771

1. 前言

1.1 Android SDK介绍

Android是基于Linux内核的一个手机操作系统,谷歌提供了开发包(Android SDK),程序员可以通过开发包开发Android App(应用程序)。Android SDK提供Java语言接口,因此Android应用是使用Java开发的。

1.2 使用纯Java开发App的缺点

在某些场合下,使用纯Java开发Android应用程序不完美,比如:

  • 有高性能算法,Java语言无法满足
  • 有跨平台需求,希望将App移植到iOS
  • 已有代码的重用

1.3 引入NDK

早在Android 1.6(2009年)时,google就提供了NDK(native development kit),NDK包括了一套Android的交叉编译环境和开发库,利用它可以编写C/C++程序,并编译成Android环境下使用的动态库,Java代码通过Jni规范,调用C/C++写的动态库。

目前最新的Android Studio 2.2中,集成了C/C++开发环境,开发人员在使用C/C++更加简单了。

2. 课程内容

NDK中文官方开发技术文档地址

下载配置NDK

NDK下载地址

配置NDK

如果不配置NDK路径,会报NDK没有配置错误

JNI开发HelloWorld

把 Include C++ support的勾打上

选择C++11和Toolchain Default均可,C++11有更多的新特性和功能

点击Finish后,进入工程目录,如图所示,除了java文件夹外多了一个cpp文件夹,cpp就是存放c和c++代码的文件夹

配置NDK开发环境中遇到的坑

Failed to find CMake

什么,CMake是什么鬼,原来,在Android Studio 2.2 后,NDK开发更加人性化了,使用了CMake,一款外部构建工具,可与 Gradle 搭配使用来构建原生库。如果您只计划使用 ndk-build,则不需要此组件。还有LLDB,一种调试程序,Android Studio 使用它来调试原生代码。

点击Install CMake and sync project,提示如下错误

Gradle sync failed: Failed to find CMake.
Install from Android Studio under File/Settings/Appearance & Behavior/System Settings/Android SDK/SDK Tools/CMake.
Expected CMake executable at D:\android-sdk\cmake\bin\cmake.exe.
Consult IDE log for more details (Help | Show Log)

原来是我使用了代理,因为之前Google的链接需要翻墙才能够使用,所以配置了某代理,但是该代理不管用,在设置中把代理去掉即可。在Google在中国开了发布会后,Google的链接可以使用了,Android开发官网也可以上了,而且翻译了大量的技术文档,方便了英语不太好的同学

打开 SDK Manager,安装上CMake和LLDB

更多更详细的NDK开发文档,请看Android官方中文文档向您的项目添加 C 和 C++ 代码

2.3 Android Java代码调用C++代码

Java部分代码

public class Jni {static  {System.loadLibrary("bc-lib"); // libbc-lib.so}private static Jni obj = new Jni();private Jni(){}public static Jni instance(){return obj;}// native接口public native boolean Login(String username, String password, String type);public native boolean Reg(String username, String password, String mobile, String email, String id);public native boolean LocationChange(double lng, double lat);public native boolean StartOrder(double lng1, double lat1, double lng2, double lat2);
}

C++部分代码

JNIEXPORT jboolean JNICALL Java_cn_xueguoliang_hc_Jni_Login(JNIEnv *env, jobject /* Jni object */, jstring jUsername, jstring jPassword, jstring type)
{return (jboolean)User::instance()->Login(j2c(env, jUsername), j2c(env, jPassword),j2c(env, type));
}JNIEXPORT jboolean JNICALL Java_cn_xueguoliang_hc_Jni_Reg(JNIEnv *env, jobject /* Jni object */,jstring jUsername, jstring jPassword, jstring mobile, jstring email, jstring id)
{return (jboolean)User::instance()->Reg(j2c(env, jUsername),j2c(env, jPassword),j2c(env, mobile),j2c(env, email),j2c(env, id));
}JNIEXPORT jboolean JNICALL Java_cn_xueguoliang_hc_Jni_LocationChange(JNIEnv *, jobject, jdouble lng, jdouble lat)
{User::instance()->LocationChange(lng, lat);return (jboolean)true;
}JNIEXPORT jboolean JNICALL Java_cn_xueguoliang_hc_Jni_StartOrder(JNIEnv *, jobject, jdouble lng1, jdouble lat1, jdouble lng2, jdouble lat2)
{return (jboolean)Order::instance()->start(lng1, lat1, lng2, lat2);
}

2.4 C++代码调用Java代码

Java代码

public class Jni {static {System.loadLibrary("native-lib");}private static Jni obj = new Jni();public static Jni instance(){return obj;}public native void HelloWorld();void callByCpp(){Log.e("JniCallback", "hello java");}
}

C++代码

extern "C"
void
Java_com_example_xueguoliang_test_Jni_HelloWorld(JNIEnv* env,jobject  This ) {std::string hello = "Hello from C++";jclass jniClass = env->FindClass("com/example/xueguoliang/test/Jni");jmethodID jmethodID1 = env->GetMethodID(jniClass, "callByCpp", "()V");env->CallVoidMethod(This, jmethodID1);return;
}

2.5 Java和C++字符串转换

jstring c2j(JNIEnv* env, string cstr)
{return env->NewStringUTF(cstr.c_str());
}string j2c(JNIEnv* env, jstring jstr)
{string ret;jclass stringClass = env->FindClass("java/lang/String");jmethodID getBytes = env->GetMethodID(stringClass, "getBytes", "(Ljava/lang/String;)[B");// 把参数用到的字符串转化成java的字符jstring arg = c2j(env, "utf-8");jbyteArray jbytes = (jbyteArray)env->CallObjectMethod(jstr, getBytes, arg);// 从jbytes中,提取UTF8格式的内容jsize byteLen = env->GetArrayLength(jbytes);jbyte* JBuffer = env->GetByteArrayElements(jbytes, JNI_FALSE);// 将内容拷贝到C++内存中if(byteLen > 0){char* buf = (char*)JBuffer;std::copy(buf, buf+byteLen, back_inserter(ret));}// 释放env->ReleaseByteArrayElements(jbytes, JBuffer, 0);return ret;
}

2.6 javah和javap

javah用于生成native接口定义,比如

javah -d ../cpp/ com.example.xueguoliang.test.Jni

javap用于生成java函数的签名,比如

javap -s Jni

C/C++在Android开发中的应用相关推荐

  1. Android开发中应避免的重大错误

    by Varun Barad 由Varun Barad Android开发中应避免的重大错误 (Critical mistakes to avoid in Android development) A ...

  2. android 4.4 禁止下拉,Android开发中禁止下拉式的实现技巧

    我们开发项目的时候,经常会看到禁止的情况,而Android开发中并没有直接调用的接口,下面是爱站技术频道小编就给大家介绍的Android开发中禁止下拉式的实现技巧,希望网友们喜欢! 分享给大家供大家参 ...

  3. 史上最全Android开发中100%会用到的开源框架整理(1/5)

    其实这个开源框架整理很久了,只是一直放在有道云笔记里面,笔者还有很多写得文章都放在有道云笔记里面,有时间都好好整理一下放出来,本篇文章也会不定期更新,由于整理的开源框架分类都有200多个,所有这次只将 ...

  4. Android开发中使用七牛云存储进行图片上传下载

    Android开发中的图片存储本来就是比较耗时耗地的事情,而使用第三方的七牛云,便可以很好的解决这些后顾之忧,最近我也是在学习七牛的SDK,将使用过程在这记录下来,方便以后使用. 先说一下七牛云的存储 ...

  5. 5 个 Android 开发中比较常见的内存泄漏问题及解决办法

    Android开发中,内存泄漏是比较常见的问题,有过一些Android编程经历的童鞋应该都遇到过,但为什么会出现内存泄漏呢?内存泄漏又有什么影响呢? 在Android程序开发中,当一个对象已经不需要再 ...

  6. Android开发中的Handler和多线程

    在Android开发中我们常常用到Handler这个类去处理消息队列中的消息,以下这个例子实现的是利用Handler传递一个消息给线程,线程运行run()方法去更新进度条的进度,以下是源代码: pub ...

  7. 在 Android 开发中使用 Kotlin 协程 (一) -- 初识 Kotlin 协程

    前言 最近在研究 Kotlin 协程,发现功能真的超级强大,很有用,而且很好学,如果你正在或计划使用 Kotlin 开发 Android,那么 Kotlin 协程你一定不能错过! 协程是什么? 我们平 ...

  8. android开发模式,Android开发中无处不在的设计模式

    Android开发中无处不在的设计模式――单例模式 Android开发中无处不在的设计模式――Builder模式 前面介绍了单例模式和Builder模式,有兴趣的见上面两个链接,这篇文章侧重介绍1下视 ...

  9. android自定义progressbar样式,Android开发中如何实现自定义ProgressBar的样式

    Android开发中如何实现自定义ProgressBar的样式 发布时间:2020-11-20 16:08:10 来源:亿速云 阅读:294 作者:Leah Android开发中如何实现自定义Prog ...

最新文章

  1. mysql 查询帖子 用户_我要用sql查询出来,我所发布的帖子和我关注的用户发布的帖子,这个sql该怎么写啊?...
  2. python访问web网页_python访问web的利器:urllib2
  3. django异常日志_5分钟教你学会Django系统错误监控
  4. “七大属性加持,三个全新升级组件”这个高性能利器有点厉害
  5. java中求组快速排序函数,如何在Java中实现快速排序?
  6. javaScript语法基础
  7. HP 360G5 IO性能提高方法
  8. System.Data.Entity.Core.MetadataException:“Unable to load the specified metadata resource.”
  9. Python报错: RuntimeError: The current Numpy installation (‘D:\\Develop\\anaconda\\lib\\site-packages\\
  10. 从棋盘左上角到右下角共有多少种走法
  11. H5 js方式实现前端视频压缩
  12. matlab阿卡曼公式,阿克曼函数--一个计算方法
  13. 【已解决】平板远程控制WIN10电脑
  14. 圈小猫游戏与天使问题——容错值理论
  15. C语言制作简谱播放器
  16. 苹果android wear教程,Android Wear/Apple Watch/WatchKit智能手表开发入门教程
  17. Linux 下使用 tplink wn823N 无线网卡
  18. 亲子编程玩Micro:bit-动力小车“麦昆”
  19. 一个良好的习惯由二十八天养成。
  20. 如何搭建一个独立博客——简明Github Pages与Hexo教程

热门文章

  1. 关于安装bitdenfender的问题
  2. swoole 协程coroutine
  3. 企业组网安全如何保障?SDWAN提供怎样的安全服务?
  4. awk是什么?awk工作原理是什么?怎么用awk?
  5. TCP首部和TCP的特性—Vecloud微云
  6. 记一个自认为写得有点复杂的sql语句
  7. 分区脚本(fdisk)
  8. [Swift]LeetCode934. 最短的桥 | Shortest Bridge
  9. GB编码与UTF8编码的转换【转载】
  10. mysql 源代码学习 博客 [lock..]