NDK 的开发流程

1、NDK开发所需要的工具

windows   需要在windows下的环境 把c代码打包成 手机能用的函数库   首先模拟手机的环境 1 NDK   .sh linux 批处理文件   .bat windows   头文件 stdio.h 编译器 interface   库函数 连接器 class 实现类   由于ndk有很多linux的批处理文件   最早基于linux开发 2 工具2 cygdriver 模拟linux系统环境 (windows操作系统)   linux系统的模拟器   linux 把所有设备都生成了一个文件 3 cdt 为了方便在eclipse开发c代码 让c代码高亮显示   c/c++ developer tools

4 adt   android developer tools 交叉编译 怎么用java代码调用c代码 生成的文件存放在armeabi (表示 arme cpu anroid binary interface)目录下

开发过程中进行将java和C进行交互的函数主要参考自NDK的安装文件下的jni.h文件中去查找对应的方法

2、具体开发步骤

  1. 定义一个c方法的接口 相当于在java代码中定义了一个接口 接口的实现方法是C语言实现的
1 public native String helloWorldFromC();
  1. 实现C代码
1 //方法名 严格按照jni的规范 
2 jstring Java_com_example_helloworldformc_MainActivity_helloWorldFromC(JNIEnv* env,jobject obj) 
  1. 生成 .mk文件  andrond.mk 告诉编译器 如何把c代码打包成函数库
1 Anroid.mk 文件 
2     LOCAL_PATH := $(call my-dir)   // 返回当前c代码目录
3     include $(CLEAR_VARS)        // 清楚了所有 已local 开头的配置文件 唯独不清楚LOCAL_PATH
4     
5     LOCAL_MODULE    := hello   // 库函数的名字  严格遵守makefile 格式  lib  .so  如果前面加lib 不会自动生成了
6     LOCAL_SRC_FILES := Hello.c
7     include $(BUILD_SHARED_LIBRARY)  // 加入库函数
  1. 把c代码 打包成函数库 用到了安装的环境cygdriver
  2. 在java代码中 引入库函数,一般用静态代码块引入
1 static{
2 System.loadLibrary("hello");// 注意事项 去掉前面的lib 后面的.so
3 }
  1. 使用方法
1 String res = helloWorldFromC() ;

3、JNI常见错误

1 错误1 忘记方法的参数 2 错误2 203-28 03:41:56.758: E/AndroidRuntime(821): java.lang.UnsatisfiedLinkError: Native method not found: com.example.error.DemoActivity.helloWorld:()Ljava/lang/String; 3 错误3 一般没有日志打印 直接报错工程停止 一般c代码有运行错误 4 错误4 在交叉编译的工具链上报错 c代码有编译错误 比如 一些函数没有声明 一些类型没有声明 少符号 5 错误5 没有Android.mk 文件 6 错误6 Android.mk 文件有错 ,一般以mk开头的报错 7 错误7 引用别人.so 函数库 需要你自己native方法对应类的包名 和之前打包成.so函数库的包名一致

4、自动生成 java本地方法对应的c代码的方法名 javah 指令 +全类名,相当于头文件

1.6 class C:\workspace\HelloWorldFromC2\bin\classes 1.7 src C:\workspace\HelloWorldFromC2\src

5、C语言回调java方法

  java代码开发好了 一个方法 C会掉java代码 javap -s 打印方法的签名 注意要cd到 C:\workspace\HelloWorldFromC2\bin\classes 传全类名 通过反射 调用java代码

 1 /*
 2 Class<?> forName = Class.forName("com.example.ndkcallback.DataProvider");
 3 Method declaredMethod = forName.getDeclaredMethod("helloFromJava", new Class[]{});
 4 declaredMethod.invoke(forName.newInstance(), new Object[]{});
 5 */
 6 
 7 ///jclass (*FindClass)(JNIEnv*, const char*);
 8 jclass clazz=(*env)->FindClass(env,"com/example/ndkcallback/DataProvider");
 9 // jmethodID (*GetMethodID)(JNIEnv*, jclass, const char*, const char*);
10 // 方法签名 参数和返回值
11 jmethodID methodId=(*env)->GetMethodID(env,clazz,"helloFromJava","()V");
12 // void (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...);
13 (*env)->CallVoidMethod(env,jobject,methodId);

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏用户2442861的专栏

muduo 4 网络库学习之Exception类、Thread 类封装中的知识点(重点讲pthread_atfork())

class Exception : public std::exception

1511
来自专栏芋道源码1024

面试问烂的 Spring AOP 原理

来源:https://www.jianshu.com/p/e18fd44964eb

2274
来自专栏软件开发

前端MVC Vue2学习总结(七)——ES6与Module模块化、Vue-cli脚手架搭建、开发、发布项目与综合示例

使用vue-cli可以规范项目,提高开发效率,但是使用vue-cli时需要一些ECMAScript6的知识,特别是ES6中的模块管理内容,本章先介绍ES6中的基...

4537
来自专栏开源优测

[接口测试 - http.client篇] 16 基于http.client之POM实战一下

概述 关注公众号回复: http.client_pom_demo 获取本文示例源码 你需要了解以下知识和技术,以便掌握后续的实例代码: http.client常...

3608
来自专栏互联网开发者交流社区

JSP语法

1905
来自专栏扎心了老铁

springboot mybatis 事务管理

本文主要讲述springboot提供的声明式的事务管理机制。 一、一些概念 声明式的事务管理是基于AOP的,在springboot中可以通过@Transacti...

5167
来自专栏Jack-Cui

Linux应用层系统时间写入RTC时钟的方法

Linux内核版本:linux-3.0.35 开发板:i.MX6S MY-IMX6-EK200 系统:Ubuntu12 前言:之前写过一篇关于如...

2220
来自专栏芋道源码1024

注册中心 Eureka 源码解析 —— EndPoint 与 解析器

目前有多种 Eureka-Server 访问地址的配置方式,本文只分享 Eureka 1.x 的配置,不包含 Eureka 1.x 对 Eureka 2.x 的...

1300
来自专栏黑泽君的专栏

day11_JSP+EL+JSTL学习笔记

    JSP全称是Java Server Pages,它和servle技术一样,都是SUN公司定义的一种用于开发动态web资源的技术。

1751
来自专栏软件开发

前端MVC Vue2学习总结(七)——ES6与Module模块化、Vue-cli脚手架搭建、开发、发布项目与综合示例

使用vue-cli可以规范项目,提高开发效率,但是使用vue-cli时需要一些ECMAScript6的知识,特别是ES6中的模块管理内容,本章先介绍ES6中的基...

1686

扫码关注云+社区

领取腾讯云代金券