ITKeyword,专注技术干货聚合推荐

注册 | 登录

学习Android JNI开发笔记

hyq4412 2016-03-10

相关推荐:android开发笔记之自定义开关按钮

今天来讲讲自定义单个控件,就拿开关按钮来讲讲,相信大家见了非常多这样的了,先看看效果:我们可以看到一个很常见的开关按钮,那就来分析分析。

什么是Android JNI开发?

  • JNI (Java Native Interface就是Java的本地接口
    JNI是Java众多开发技术中的一门,意在利用本地代码,为Java程序提供 更高效,更灵活的拓展。应用场景包括:对运行效率敏感的算法实现、跨平台应用移植、调用系统的底层驱动、调用硬件等。尽管Java一贯以其良好的跨平台性 而著称,但真正的跨平台之王,应该是C/C++,因为当前世上90%的系统都是基于C/C++编写的。Java的跨平台,是以牺牲效率换来对多种平台的兼 容性,因而JNI可以说是Java短板的补充!为什么一直说Android比IOS要卡顿? 原因在于 Android的App是基于Java开发的,IOS的是基于Object-C开发的,区别在于同样的操作,在IOS上一条指令完成,在Android上 则需要多条指令才能完成(在应用层大量使用了本地库,并优化了系统的架构,以提升 Android系统整体的操作反应,另外使用JNI更加安全。

交叉编译

  • 在一个平台下编译出另一个平台可以执行的二进制程序
  • CPU平台:arm,x86,mips
  • 系统平台:Windows、Linux、Mac OS
  • 原理:模拟另一个平台的特性去编译代码
    • 源代码->预编译->编译->链接->可执行程序
  • 工具链:一个工具使用完毕自动使用下一个

常见工具

  • NDK:native development kits
  • CDT:C/C++ development tools
    • eclipse插件
    • 高亮显示C关键字
  • cygwin:Windows平台下的Linux命令行模拟器

NDK目录结构

  • docs:帮助文档
  • build/tools:Linux批处理文件
  • platforms:存放开发jni用到的h头文件和so动态链接库
  • prebuilt:预编译使用的工具
  • sample:使用jni的案例
  • source:NDK的部分源码
  • toolchains:工具链
  • ndk-build.cmd:编译打包C代码的指令

JNI

步骤

  1. 定义并调用本地方法
  2. 创建jni文件夹
  3. jni文件夹里创建c文件
  4. c文件中实现本地方法,

    相关推荐:android开发笔记之打造终极适配器

    大家看到这个标题是不是觉得很诧异呢?什么叫终极适配器,其实就是这种适配器是万能的,所有需要使用适配器的组件,都可用这一个适配器就行。既然这

    格式如下

    //返回值与本地方法一致
    //函数名:Java_包名_类名_本地方法名
    //env:结构体二级指针,该结构体中封装了大量的函数指针,可以帮助程序员实现某些常用功能
    //thiz:本地方法调用者的对象(MainActivity的对象)
    jstring Java_com_itheima_helloworld1_MainActivity_helloFromC(JNIEnv* env, jobject thiz)
    
  5. 创建Android.mk文件,指定要编译的c文件
  6. 在jni目录下,执行ndk-build.cmd,编译打包出so动态链接库
  7. 在java代码中加载动态链接库
  8. 部署,运行

常见错误

  • 找不到类库
    • 没有添加对应平台的支持
    • 类库名写错了
  • 找不到本地方法
    • 忘记加载类库
    • c函数名写错了

javah指令

  • 自动生成jni样式的头文件,头文件中就包含了我们需要的函数名
  • 1.7:在src目录下使用:javah com.itheima.helloworld2.MainActivity
  • 1.6:在bin/classes目录下使用:

添加本地支持

  • 自动生成jni文件夹
  • 自动生成c文件和Android.mk文件
  • 指定jni.h头文件的路径,相当于关联源码
  • 不需要再去jni目录下使用ndk-build.cmd指令,项目部署时,会先打包编译so类库再去部署到手机上

数组传递

  • java的数组是对象,传递对象是传递对象的地址,c函数中修改了地址上的值,所以数组的值就改变了

javap

  • 打印指定类中所有方法的签名
  • 在bin/classes目录下使用:javap -s com.itheima.helloworld2.MainActivity

C++实现JNI

  • C++中的JNIEnv和C的JNIEnv不是同一个结构体
  • C++的 JNIEnv 是jni.h中定义的 _JNIEnv
  • C的 JNIEnv 是jni.h中定义的 JNINativeInterface*
  • _JNIEnv结构体中的函数其实就是调用了JNINativeInterface中的同名函数指针
  • C++中函数要先声明才能使用

分支C进程

  • fork函数分支一个C进程,返回子进程的pid
  • 子进程执行fork函数时不会再分支进程了,返回0

undefined reference to `__android_log_print’ 解决方法

  • 用jni去调用C程序,但是C代码里有用到LOGI,编译的时候报错,说undefined reference to `__android_log_print’
    在Android.mk里加入LOCAL_LDLIBS := -llog
    注意android.mak 里有一行include $(CLEAR_VARS)
    必须把LOCAL_LDLIBS :=-llog放在它后面才有用,否则相当于没写 !!!!!

无法启动此程序,因为计算机中丢失AdbWinApi.dll

  • 要把eclipse下platform-tools下的AdbWinApi.dll和adb.exe放到C:Windows\SysWOW64目录下,不是system32下。
    这样可以通过windows终端操作adb安装手机软件和启动关闭adb等一系列操作!

相关推荐:android开发笔记之权重(layout_weight)

我相信大家在布局文件中都用过权重(layout_weight)吧,当然这只有在线性布局(Linearlayout)中才有的,可是很多人也许都只是简单的理解为比。其

什么是Android JNI开发?JNI (Java Native Interface就是Java的本地接口 JNI是Java众多开发技术中的一门,意在利用本地代码,为Java程序提供 更高效,更灵活的拓展。应用场景包括:对运行...

相关阅读排行


用户评论

游客

相关内容推荐

最新文章

×

×

请激活账号

为了能正常使用评论、编辑功能及以后陆续为用户提供的其他产品,请激活账号。

您的注册邮箱: 修改

重新发送激活邮件 进入我的邮箱

如果您没有收到激活邮件,请注意检查垃圾箱。