问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

android 调用c语言包会速度更快吗

发布网友 发布时间:2022-04-24 06:24

我来回答

1个回答

热心网友 时间:2022-04-27 18:17

  在安卓平台上开发应用,通用的语言是 Java ,而对于从其它平台迁移到安卓的项目、产品,或者对于惯用 C/C++ 编程的开发人员来讲,会希望复用已有的 C/C++ 代码。安卓平台提供了复用 Native 代码的途径,也提供了编译 C 代码的环境和工具链: NDK 。 NDK 是一套工具链,有了它,在安卓上使用 C 语言成为可能。其实安卓原本是在 Linux 上套了个 Java 环境,要说不能用C 那才是不可思议的事儿,只是 Google 没完全开放而已(话说我到现在都在腹黑,为么不能让 C 程序员在安卓上活得自在些呢,简直是人为制造障碍)。
  安卓平台上服用 C 代码有两种方式:

  JNI
  原生 C 可执行程序

  JNI 方式
  JNI 原本是Java 提供的一种复用 C 代码的框架,安卓又对此进行了一些扩充,加了个 AIDL 用在服务框架中,搞了一套工具,在使用 Android.mk 编译时可以根据 AIDL 文件自动生成对应的 Java 代码并编译。
  使用 JNI 主要是把 C 代码编译成动态库,在 Java 中调用。使用的步骤大概是这样的:

  在 Java 代码中声明 native 方法
  在 JNI(桥接 C 代码的这部分 C 代码称之为 JNI 层)层按照命名规则实现与 Java 层对应的本地方法
  在 Java 层加载 C 动态库

  JNI 方式的例子,如 Qt on Android ,Vitamio ,还有安卓框架本身中的一些例子,如 ServiceManager , android.util.Log 。

  原生 C 可执行程序

  安卓本是 Linux ,调用 Native 可执行程序是自然而然的途径。 Java 也提供了语言层面的支持,Runtime.exec() 函数就是干这个的。通过 exec() 启动进程,可以读取 Native 进程的标准输出,可以向 Native 进程的标准输入写入数据。
  调用原生可执行程序的方式的例子, WifiManager 在连接无线网络时会通过控制接口和 wpa_supplicant (用于无线连接的 wpa_suppliacant ,是原生C可执行程序)通信传递诸如扫瞄接入点、选择网络、连接网络等指令。
  还有,有些安卓系统机顶盒上自带的宽带拨号(PPPoE)程序,也是 C 可执行程序, Java 层的 PPPoEService 最终通过调用pppd/ppppoe 这样一些程序来执行实际的拨号过程。
  还有,我们常说的 root ,其实也是通过调用一个叫 su 的程序来实现的。
  我们在实际开发中也可以这么用,比如想看某个目录下都有什么文件,可以直接调用 ls 命令,读取它的标准输出。
  Java 和 C 程序通信问题
  我们在安卓上通过 Java 调用 C 代码时还会遇到进程或线程间通信的问题。
  这里专门说下 Java 进程和 C 进程、Java 进程和 C 共享库的通信问题。
  有时我们的需求很简单,阻塞式调用 C 代码,拿到计算结果就达到目的了。比如你通过 JNI 调用 C 共享库的一个 Hash 函数,又比如你通过 Runtime.exec() 调用一个 Native 可执行程序来计算 Hash 读取其标准输出获得结果。这些场景足够简单,你可以不考虑 Java 和 C 共享库或者 C Native 可执行程序间的通信,反正是一锤子买卖也没啥状态要维护的。
  但是还有一些复杂的应用,我们必须在 Java 和 C 之间建立一种长期的通信机制。
  还是举无线连接的例子好了,有兴趣的读者可以浏览 wpa_supplicant 的源代码,它提供了基于 dbus、unix domain socket 两种方式的控制接口。
  其实 Linux 常用的进程间通信机制,如 管道pipe 、socket 、信号,也都可以用于 Java 层和 C 层的通信,而且安卓框架就这么用了。举个例子,我们都很熟悉的安卓世界的第一个进程 Zygote(实际是 app_process ,启动后更名为 Zygote ),有一个功能就是启动 Java 进程,当我们要启动一个 APK ,该 APK 的进程几经辗转最终是由 Zygote 启动的(可以进程间共享 Java 类库、C 共享库,大大节省资源也加快进程启动过程),而 Zygote 正是通过 socket 接受命令的。
  再举个信号的例子,我们看到很多进程管理类的应用,其实都是使用 android.os.Process 来杀进程,而 Process.kill() ,实际上就是给目标进程发送了一个信号,非常标准的 Linux 机制。
  还有一个常用的 Java 和 C Native 可执行程序进程间通信的机制:标准输入输出。我们可以向一个进程的标准输入写入数据,也可以从它的标准输出读取数据。那么我们就可以定义一套控制协议用来通信。
  像管道 pipe、socket 既可以用于进程间通信(Java 和 C Native 可执行程序),也可以用于进程内通信( Java 和 C 共享库)。那么什么场景下我们会这么用呢?前面的无线连接服务程序 wpa_supplicant 可以给我们一些提示。
  假如我们用 C 实现了一个服务,而 Java 层需要经常访问这个服务并且需要得到反馈,那么就可以这么干。
  试着说一个场景,我们用 C 实现了一个可以支持并行下载的模块(单线程 select 模型),而 Java 层会频繁地下载图片(安卓上 Java 层貌似没有简单易用占用资源又少的http 下载库),比如一个云相册类的应用或视频类应用,我们就可以把下载动作委托给 C 进程。
  进程间通信,安卓框架中还有一个在 Linux IPC 框架之上扩展出来的新框架 Binder ,很多 Native 系统服务使用 Binder 框架,比如 AudioFlinger ,我们在 Java 层调用 AudioManager 设置音量的功能时,最终就是通过 Binder 框架使用了 Native 系统服务 AudioFlinger 的功能,是典型的跨进程调用,但是作为 Java 程序,完全不用关心这个。
  想详细了解 Binder 的读者,可以进一步学习。这里提一下 Binder 的*:不是所有 C 程序都可以使用 Binder 来注册服务,只有被授权的服务如 media.player ,media.camera 之类的 Native 系统服务才可以,如果你是系统开发,可以通过修改授权列表(通过 UID 控制)来允许你的 C 程序注册服务,而作为应用开发者,就别妄想了,还是考虑使用管道pipe、socket 或者标准输入输出稳妥些。
  编译 C 可执行程序
  为安卓平台编译 C 可执行程序,有几个方法:

  使用 NDK ,使用 Android.mk
  手动使用预编译的 gcc 编译
  使用 Qt 5.2 ,参考《Windows下Qt 5.2 for Android开发入门》和《Windows下Qt for Android 编译安卓C语言可执行程序》

  在 APK 中集成和使用 C 可执行程序
  怎样在 APK 中集成和使用一个 C 可执行程序呢?遵循下列步骤即可:

  可以把可执行程序放在 assets 目录下,这样打包成 APK 时会自动打包
  APK 运行时访问 assets 文件夹内的资源,释放可执行程序,添加可执行权限
  使用 Runtime.exec() 启动可执行程序

  好啦,总算说了个大概,希望对你有所帮助。
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
企业培训学到了什么 培训感悟简短 有关培训的感悟 通过培训学到什么 培训你学到了什么 领导问培训学到什么怎么回复 Linux系统安装FTP服务器 Linux系统的网络文件共享 建筑的七盏明灯的内容简介 面向对象设计七大原则 简单说 交互设计七大定律 猪的那些东西是宝? 梦见孙子被人买了我抱回来了好着吗? 猪身上有什么东西? linux c 和android 选哪个啊。 猪身上有哪些“宝贝”呢?哪些东西吃了大补? 梦到儿子抱给我抱回来个孙子? 梦见儿媳妇抱着孙子回来了? C语言与安卓开发有什么关系。 猪吃什么食物? android是一种什么语言 猪身上的所有东西是不是都可以吃? C、C++、ANDROID、JAVA各有什么区别? 猪体内的东西 是什么? 生活用品中哪些用了猪身上的东西? 电脑游戏全屏退了之后,电脑屏幕变大了很多,部分图标不能显示怎么办? 电脑屏幕显示太大看不全,调了分辨率不管用 我电脑屏幕变这么大而且打开什么都看不见怎么办? QQ音乐怎么取消默认收藏 搜狗浏览器的默认收藏夹在哪个盘里啊?!并且怎么修改默认收藏夹的存放位置? qq空间音乐盒中添加网络音乐到默认收藏,收藏夹怎么没有 猪内脏有哪些? 梦见儿子媳妇领着孙子回家 梦见儿媳妇准备把孙子送回家来? 大三在读,有一些android和C的基础,想利用空余时间学习ios和android开发,可以两个同时学吗? 猪最主要的食物是什么? 猪吃什么东西? java学android好还是c学android好 梦见带孙子回家并且在路上遇到好心人? 猪是什么东西 梦见走散了的亲人带着孙子回来了? 猪吃的东西叫什么 Android NDK Jni 开发C和C++的区别 猪身上 割下来的两个什么东西? Android开发环境下C/C++编程到底是什么意思? 梦见离婚儿媳妇带孙子一起回家是好是坏? 安卓开发需要什么需要c语言和java语言,用哪个? 梦见孙子光身我抱在怀中 奶奶梦见自己的孙子回来了在喊自己是什么意思? 做梦跟人打架然后抱孙子回家把孙子胳膊摔掉环了,这梦好不好? 奶奶梦见孙子带回家一捆多嫩绿的韭菜放桌上是啥意思啊?