JNI入门学习总结

一、序言

NDK开发需要用到jni,项目中的第三方库经常有个.so文件有什么用,为啥加密不用java写呢?等等,再见我不知道...即使知道也仅仅是概念性的。现在我知道了!!

二、JNI的好处

两个字“装逼!!”,学了之后在同行看来会有种高大上的感觉,虽然自己心里知道很简单的,但是别人不会的东西,在他们眼里,就是高大上的。我有时很赞同:装逼就是一直学习新技术的动力。也是为了升职加薪,努力为以后的白富美创造更多幸福!!

三、环境搭建

参考:http://blog.csdn.net/u011176685/article/details/50450585

里面是针对64位操作系统的,去云盘下载一下本地安装就行。个人不推荐在线安装。因为我被那个在线安装折腾死了。

四、Java代码调用C代码

1.在MainActivity里面定义一个C方法的接口,相当于在java代码中定义一个接口,接口的实现方法是通过C语言实现的

public native String helloWorldFromC()

 

2.C语言实现接口方法,方法的命名严格按照jni规范来(env指向java虚拟机的环境,obj代表对象)

Java_com_example_helloworldformc_MainActivity_helloWorldFromC(JNIEnv* env,jobject obj){}

 

3.在项目文件创建jni文件夹,生成.mk文件。.mk文件主要用于告诉编译器如何把C代码打包成函数库

Hello.c为刚才创建的实现接口方法的文件

LOCAL_PATH := $(call my-dir)   // 返回当前c代码目录
   include $(CLEAR_VARS)        
   LOCAL_MODULE    := hello   // 库函数的名字  严格遵守makefile 格式  lib  .so  如果前面加lib 不会自动生成了
   LOCAL_SRC_FILES := Hello.c
   include $(BUILD_SHARED_LIBRARY)  // 加入库函数

4.交叉编译,利用前面安装的软件cygwin,把c代码打包成函数库.so文件


5.在java代码中引入库函数,注意事项去掉前面的lib 后面的.so

System.loadLibrary("hello");

6.使用方法

System.out.println(helloWorldFromC()
7.小总结:jni其实就相当于java和c语言的翻译器,在android-ndk-r8c里面的jni.h头文件,有两者相互对应的方法,类型等等。在编程中可以进行查找参考。

五、C语言回调Java方法(java中开发好的方法,c语言调用

1.原理:通过反射调用java代码(在java里面调用java类DataProvider里面的helloFromJava方法)

Class<?> forName = Class.forName("com.example.ndkcallback.DataProvider");
Method declaredMethod = forName.getDeclaredMethod("helloFromJava", new Class[]{});
declaredMethod.invoke(forName.newInstance(), new Object[]{});

2.C代码中,其实就是通过jni把那个方法翻译过来

注意“()V”是方法的签名,cmd命令窗口cd到 D:\workspace\HelloWorldFromC2\bin\classes ,你的工程文件存放class的地方,然后javap -s 打印方法的签名,需要传完整的包名。

jclass clazz=(*env)->FindClass(env,"com/example/ndkcallback/DataProvider");
// 方法签名  参数和返回值
jmethodID methodId=(*env)->GetMethodID(env,clazz,"helloFromJava","()V");
(*env)->CallVoidMethod(env,jobject,methodId);

3.然后就是java中调用C方法,c回调java方法

六、jni常见错误

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

七、本人是攻城狮一只,正在拼命努力的向更高的地方跑。有兴趣的话可以加QQ群:494364346。大家一起努力奋斗,相互分享。

转载请注明转自:http://blog.csdn.net/u011176685/article/details/50455030

欢迎关注个人微信公众号,专注于Android深度文章和移动前沿技术分享



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值