中易网

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

答案:1  悬赏:0  
解决时间 2021-12-20 15:40
android调用c语言包会速度更快吗
最佳答案
在安卓平台上开发应用,通用的语言是 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() 启动可执行程序

  好啦,总算说了个大概,希望对你有所帮助。
我要举报
如以上问答内容为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
自给的意思是什么?自给的释义是什么啊?
出刺的意思是什么啊?请解释下!
挽世的意思是什么?挽世的释义是什么啊?
輕綃的意思是什么?輕綃的释义是什么啊?
我是一个十四岁的男孩,我性格很内向,总是想
槃樂的意思是什么?槃樂的释义是什么啊?
宿州小儿粮仓加盟代理怎么样前景好吗?
搜逷的意思是什么啊?请解释下!
北京奥运大厦最近地铁站是哪站
玄奘法师为何最想亲近的是弥勒菩萨,而不是阿
二月河帝王系列真实度有多少?
身子的意思是什么?身子的释义是什么啊?
真爱电动车是不是名牌
ntimediamaker9怎么重新安装
够瞧的意思是什么啊?请解释下!
推荐资讯
华为mate7无线网转移动网无法自动连结,需要手
如果已经获得物理和生物竞赛省级一等奖,能否
有谁记得组合4inlove请问这个名字是什么意思
工团主义的意思是什么?工团主义的释义是什么
兰陵县安全生产监督管理局办公地址在什么地方
猫咪能不能喂比瑞吉幼猫粮
工商生育保险注销结算登记表怎么填写
近几年来,潘阳湖加强了湿地保护,生态环境得到
中国农业银行江西省高安支行行长是谁现任
这句话的英文翻译~生本教育是以“一切为了学
扬子空调KFRd-35GW/081-E3怎么样
lol西门吹雪游戏叫什么名
手机登qq时,显示手机磁盘不足,清理后重新登
刺客的套装怎么选啊?