交叉编译

  • 在一个平台上去编译另一个平台上可以执行的本地代码
  • cpu平台 arm x86 mips
  • 操作系统平台 windows linux mac os
  • 原理 模拟不同平台的特性去编译代码

jni开发工具

  • ndk native develop kit
  • ndk目录
    • docs 帮助文档
    • platforms 好多平台版本文件夹 选择时选择项目支持的最小版本号对应的文件夹
    • 每一个版本号的文件夹中放了 不同cpu架构的资源文件
    • include文件夹 jni开发中常用的 .h头文件
    • lib 文件夹 google打包好的 提供给开发者使用的 .so文件
    • samples google官方提供的样例工程 可以参考进行开发
    • android-ndk-r9d\build\tools linux系统下的批处理文件 在交叉编译时会自动调用
    • ndk-build 交叉编译的命令
  • cdt eclipse的插件 高亮C代码 C的代码提示

jnihelloworld

  • jni开发的步骤

    • ①写java代码 声明本地方法 用到native关键字 本地方法不用去实现
    • ②项目根目录下创建jni文件夹
    • ③在jni文件夹下创建.c文件
    • 本地函数命名规则: Java_包名类名本地方法名
    • JNIENV* env JNIEnv 是JniNativeInterface这个结构体的一级指针
    • JniNativeInterface这个结构体定义了大量的函数指针
    • env 就是结构体JniNativeInterface这个结构体的二级指针
    • (*env)->调用结构体中的函数指针
    • 第二个参数jobject 调用本地函数的java对象就是这个jobject
    • ④ 导入

jni开发中的常见错误

  • java.lang.UnsatisfiedLinkError: Native method not found: 本地方法没有找到

    • 本地函数名写错
    • 忘记加载.so文件 没有调用System.loadlibrary
  • findLibrary returned null
    • System.loadLibrary(“libhello”); 加载动态链接库时 动态链接库名字写错
    • 平台类型错误 把只支持arm平台的.so文件部署到了 x86cpu的设备上
      • 在jni目录下创建 Application.mk 在里面指定
      • APP_ABI := armeabi

        APP_PLATFORM := android-14
  • javah
    • jdk 1.7 项目 src目录下运行javah
    • jdk 1.6 项目 bin目录下 classes文件夹
    • javah native方法声明的java类的全类名

jni简便开发流程

  • ① 写java代码 native 声明本地方法
  • ② 添加本地支持 右键单击项目->andorid tools->add native surport
    • 如果发现 finish不能点击需要给工作空间配置ndk目录的位置
    • window->preferences->左侧选择android->ndk 把ndk解压的目录指定进来
  • ③ 如果写的是.c的文件 先修改一下生成的.cpp文件的扩展名 不要忘了 相应修改Android.mk文件中LOCAL_SRC_FILES的值
  • ④ javah生成头文件 在生成的头文件中拷贝c的函数名到.c的文件
  • ⑤ 解决CDT插件报错的问题
  • 右键单击项目选择 properties 选测 c/c++ general->paths and symbols->include选项卡下->点击add..->file system 选择ndk目录下 platforms文件夹 对应平台下(项目支持的最小版本)

    usr 目录下 arch-arm -> include 确定后 会解决代码提示和报错的问题
  • ⑥编写C函数 如果需要单独编译一下c代码就在c/c++视图中找到小锤子
  • 如果想直接运行到模拟器上 就不用锤子了
  • ⑦ java代码中不要忘了 system.loadlibrary();

C代码中向logcat输出内容

Android.mk文件增加以下内容
LOCAL_LDLIBS += -llog
C代码中增加以下内容
#include <android/log.h>
#define LOG_TAG "System.out"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)

* define C的宏定义 起别名 #define LOG_TAG “System.out” 给”System.out”起别名LOG_TAG

* #define LOGI(…) android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS)

* 给 __android_log_print函数起别名 写死了前两个参数 第一个参数 优先级 第二个参数TAG

* VA_ARGS 可变参数的固定写法

* LOGI(…)在调用的时候 用法跟printf()一样

C代码回调java方法

  • ① 找到字节码对象

    • //jclass (FindClass)(JNIEnv, const char*);
    • //第二个参数 要回调的java方法所在的类的路径 “com/itheima/callbackjava/JNI”
  • ② 通过字节码对象找到方法对象
    • //jmethodID (GetMethodID)(JNIEnv, jclass, const char*, const char*);
    • 第二个参数 字节码对象 第三个参数 要反射调用的java方法名 第四个参数 要反射调用的java方法签名
    • javap -s 要获取方法签名的类的全类名 项目/bin/classes 运行javap
  • ③ 通过字节码创建 java对象(可选) 如果本地方法和要回调的java方法在同一个类里可以直接用 jni传过来的java对象 调用创建的Method
    • jobject obj =(*env)->AllocObject(env,claz);
    • 当回调的方法跟本地方法不在一个类里 需要通过刚创建的字节码对象手动创建一个java对象
    • 再通过这个对象来回调java的方法
    • 需要注意的是 如果创建的是一个activity对象 回调的方法还包含上下文 这个方法行不通!!!回报空指针异常
  • ④ 反射调用java方法
    • //void (CallVoidMethod)(JNIEnv, jobject, jmethodID, …);
    • 第二个参数 调用java方法的对象 第三个参数 要调用的jmethodID对象 可选的参数 调用方法时接收的参数

JNI开发流程的更多相关文章

  1. JNI开发流程-JNI/NDK【转】

    本文转载自:http://wiki.jikexueyuan.com/project/jni-ndk-developer-guide/workflow.html 开发流程 JNI 全称是 Java Na ...

  2. JNI/NDK开发指南(一)—— JNI开发流程及HelloWorld

    转载请注明出处:http://blog.csdn.net/xyang81/article/details/41777471 JNI全称是Java Native Interface(Java本地接口)单 ...

  3. 编程基础知识——Java JNI开发流程(2)

    android中使用jni调用本地C++库 android平台上的本地库文件后缀 .so.类似windows上的dll文件. 要在android上使用jni.首先须要下载android ndk. 操作 ...

  4. NDK学习笔记-JNI开发流程

    JNI(Java Native Interface)Java本地化接口,Java调用C/C++,C/C++调用Java的一套API接口 实现步骤 在Java源文件中编写native方法 public ...

  5. Android的JNI开发

    变量的定义 int i; typedef int x;//定义一个int x数据类型 x a=10; printf("size=%d",sizeof(i));//获取int类型长度 ...

  6. JNI开发(2)——开发实战

    JNI开发(1)--概述.环境搭建.必要知识点 JNI开发(2)--开发实战 本篇是重头戏:JNI实战开发.假设你对于 JNI.NDK 还没概念的话 那么观看本篇 也是没有太大难度的 ,哈哈哈哈! ! ...

  7. android下JNI开发

    android下JNI开发 what 什么是JNI JNI java native interface native本地 java本地接口 通过JNI可以实现java和本地代码之间相互调用 jni可以 ...

  8. Android jni简便开发流程

    <Android jni helloworld>中介绍了开发jni helloworld的步骤,本文将介绍jni简便开发流程 ① 写java代码 native 声明本地方法 ② 添加本地支 ...

  9. Android游戏开发实践(1)之NDK与JNI开发02

    Android游戏开发实践(1)之NDK与JNI开发02 承接上篇Android游戏开发实践(1)之NDK与JNI开发01分享完JNI的基础和简要开发流程之后,再来分享下在Android环境下的JNI ...

随机推荐

  1. 【MySQL】(二)InnoDB存储引擎

    InnoDB是事务安全的MySQL存储引擎,设计上采用了类似于Oracel数据库的架构.通常来说,InnoDB存储引擎是OLTP应用中核心表的首选存储引擎.同时,也正是因为InnoDB的存在,才使My ...

  2. vue教程(二)--过滤器和监视改动功能

    过滤器filter: 1.将数据进行添油加醋的操作. 2.过滤器分两种: 组件内的过滤器(组件内有效). 全局过滤器 组件内:filters:{过滤器名:过滤器函数fn},fn内通过return 返回 ...

  3. Jmeter CSV config使用

    1.添加线程组,自己给线程组命名 2.添加CSV data set config 如上,filename是文件的名字 新增.txt文件,将变量写在文件中,完成后,更名为.csv:变量之间用逗号隔开(第 ...

  4. 转发后找不到css

    当在jsp中引入css时,如果其相对路径相对于当前jsp文件的,而在一个和这个jsp的路径不一样的servlet中forward这个jsp时,就会发现这个css样式根本没有起作用. 这是因为在serv ...

  5. 实现万行级excel导出---poi--ooxm的应用和采坑

    xl_echo编辑整理,欢迎转载,转载请声明文章来源.欢迎添加echo微信(微信号:t2421499075)交流学习. 百战不败,依不自称常胜,百败不颓,依能奋力前行.--这才是真正的堪称强大!! - ...

  6. 【Spring】The matching wildcard is strict……

    applicationContext.xml 文件抛出了这个异常信息. 解决方法: 需要在 namespace 后加上对应的 schemaLocation,如下所示: <?xml version ...

  7. 【Android】Failed to convert @drawable/picture into a drawable

    刚使用 eclipse 遇到了这个问题,图片的效果未显示出来,上网查找后发现这其实不算是问题:重启下工程或 eclipse 就行了. PS: 直接运行工程也可以,不影响效果.

  8. [重磅开源] 比SingleR更适合的websocket 即时通讯组件---ImCore开源了

    有感而发 为什么说 SignalR 不合适做 IM? IM 的特点必定是长连接,轮训的功能用不上. 因为它是双工通讯的设计,用hub.invoke发送命令给服务端处理业务,其他就和 ajax 差不多, ...

  9. Docker 容器高级操作[Docker 系列-3]

    关注公众号,大家可以在公众号后台回复“博客园”,免费获得作者 Java 知识体系/面试必看资料. 上篇文章向读者介绍了一个 Nginx 的例子,对于 Nginx 这样一个容器而言,当它启动成功后,我们 ...

  10. Tomcat 单(多)实例部署使用

    一.前言 (一).概述 Tomcat 是由 Apache 开发的一个 Servlet 容器,实现了对 Servlet 和 JSP 的支持,并提供了作为Web服务器的一些特有功能,如Tomcat管理和控 ...