• 安卓中如何调用jni


    ##指针和数组之间的关系
    * 数组名就是数组元素的首地址
    * 数组是一块连续的内存空间,每个元素之间的距离跟数据的类型有关
    * 数组名字取地址,得到的还是数组的首地址
    * arr[i]  ==  *(arr+i)
    ##指针的运算
                只能计算连续的内存空间
    ##动态内存和静态内存
    * 动态内存 
    - new 对象这就是动态申请内存
    * 静态内存
    - 方法体 int i; 静态内存
    ##结构体
    *跟java里面的class非常类似
    *编译器,把结构体进行一个对齐操作。 提高内存寻址的效率
    ##联合体
    *联合体中只能存储一种数据类型的数据
    *如果有多个数据类型,那么联合体的长度是联合体中最长类型的长度
    ##宏定义
    *就是定义别名,关键字是type of
    #JNI开发的流程
    规范,中间人,中间件 c/c++ <---> java
    NDK: native develop kits 谷歌给安卓程序员提供的一个做jni开发的工具
    ##NDK开发工具的目录结构
    - doc 开发帮助文档
    - build c语言编译的工具链 cygwin 
    - platform 平台: 指定了编译针对的Android平台
    - arm  处理器架构  手机平板电脑 三星 摩托 
    - mips 处理器架构  开源的处理器架构(龙芯)
    - x86  处理器架构  台式机 笔记本(intel,AMD)
    >交叉编译: 使用交叉编译工具链在一个平台下编译出来另外一个平台可以运行的二进制代码
    >c词法分析 语法分析 编译原理
    - prebuild 预编译工具目录
    .java -->.class --->jvm -->解释执行(java翻译机器语言)
    .c --> .o --->根据机器类型链接 -->机器代码
    - sample 示例代码
    - source 工具链的源码
    - tool chains 工具链
    - ndk-build.cmd 编译c代码的工具脚本
    ## 开发流程
    * JAVA程序员 搞Android开发
    * c程序员 搞c开发,实现业务功能(例如用c实现一个加密算法)
    * JNI工程师(胶水)
    - 定义java的接口
    - 定义c的接口
    ##cdt Eclipse的插件
    c/c++ develop tools,可以让c/c++的语法高亮显示。
    编译c代码。ndk交叉编译的工具链。
    ##JNI开发的流程
    1. 现在java代码里面声明一个native的方法
      public native String helloFromC();
    2. 在Eclipse的工程目录下创建一个文件夹 名称jni
    3. 编写c代码,按照规范编写
    jstring Java_com_itheima_hellojni_MainActivity_helloFromC(JNIEnv* env,jobject obj){
    char* str = "hello from c !!";
    //在jni规范里面 在jni环境的结构体里面
    //jstring     (*NewStringUTF)(JNIEnv*, const char*);
    //转化成了java的字符串
    return (*(*env)).NewStringUTF(env,str);
    }
    Java_包名_类型_方法名(jvm虚拟机的指针,调用者对象)
    4. ndk-build.cmd指令编译c代码
    5. 配置Android.mk文件
    #指定编译的文件夹  指定当前文件目录
    LOCAL_PATH := $(call my-dir)
    #编译器会定义很多的临时变量,中间变量,最好清空所有的中间变量。
    include $(CLEAR_VARS)
    #编译出来模块的名称
    LOCAL_MODULE    := hello
    # 编译的源代码的名称
    LOCAL_SRC_FILES := hello.c
     
    #编译一个动态库,静态库
    #静态库 文件名.a   包含所有的函数并且函数运行的依赖,体积大,包含所有的API
    #动态库 文件名.so  包含函数,不包含函数运行的依赖,体积小,运行的时候,去操作系统寻找需要的API
    include $(BUILD_SHARED_LIBRARY)
    6. 生成一个.so的动态链接库
    7. 在java代码里面,把动态链接库加载到jvm虚拟机
    static{
    System.loadLibrary("库文件名称不带前缀,后缀名");
    }
    8. 像调用一般java代码一样调用native的方法
    ##JNI应用场景
    银行手机客户端应用。钱。
    JAVA 非常容易反编译。
     
    * c代码已经写好了()
    * java代码和c代码同时开工
    ##JNI开发的常见错误
    1. 写错了load的library 
    java.lang.UnsatisfiedLinkError: Couldn't load hell0: findLibrary returned null
     
    2. Android.mk文件编写错误
    /jni/Android.mk:4: *** missing separator.  Stop.
     
    3. LOCAL_MODULE配置不能有扩展名
    //jni/Android.mk:hello.so: LOCAL_MODULE_FILENAME must not contain a file extension
    4. c或者c++的源文件名称配置错误
    objs/hello/helo.o'.  Stop.
    5. 如果使用了错误的cpu平台
    java.lang.UnsatisfiedLinkError: Couldn't load hello: findLibrary returned null
    添加多cpu平台的支持 APP_ABI := armeabi armeabi-v7a x86
    6. c语言方法名称错误,导致java代码无法寻找到c代码
    Caused by: java.lang.UnsatisfiedLinkError: Native method not found: com.itheima.hellojni.MainActivity.helloFromC:()Ljava/lang/String;
    7. 应用程序闪退
    06-25 07:31:46.698: I/dalvikvm(1871):   #00  pc 0008ee6d  /system/lib/libdvm.so
    06-25 07:31:46.698: I/dalvikvm(1871):   #01  pc 000738ca  /system/lib/libdvm.so
    06-25 07:31:46.698: I/dalvikvm(1871):   #02  pc 000739f4  /system/lib/libdvm.so
    06-25 07:31:46.698: I/dalvikvm(1871):   #03  pc 00038f5b  /system/lib/libdvm.so
    06-25 07:31:46.698: I/dalvikvm(1871):   #04  pc 0003bdbd  /system/lib/libdvm.so
    要么就是c代码有逻辑错误
    要么编码问题,中文或者空格路径
    ##KISS
    Keep it simple stupid
  • 相关阅读:
    Python学习之旅(十二)
    Python学习之旅(十一)
    Python学习之旅(十)
    Python学习之旅(十)
    Python学习之旅(九)
    Python学习之旅(八)
    WPF 画刷应用
    WP8 学习 在APP.XAML中加入Resources
    WP8 学习 ApplicationBar 的创建 XAML代码
    WP8 学习 Onnavigatedto和OnnavigatedFrom的区别
  • 原文地址:https://www.cnblogs.com/itlyh/p/6047174.html
Copyright © 2020-2023  润新知