• 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();
    2. 实现C代码
      1 //方法名 严格按照jni的规范 
      2 jstring Java_com_example_helloworldformc_MainActivity_helloWorldFromC(JNIEnv* env,jobject obj)  
    3. 生成 .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)  // 加入库函数
    4. 把c代码 打包成函数库 用到了安装的环境cygdriver
    5. 在java代码中 引入库函数,一般用静态代码块引入
      1 static{
      2 System.loadLibrary("hello");// 注意事项 去掉前面的lib 后面的.so
      3 }
    6. 使用方法
      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:workspaceHelloWorldFromC2inclasses
    1.7 src
    C:workspaceHelloWorldFromC2src

     

    5、C语言回调java方法

      java代码开发好了 一个方法 C会掉java代码 javap -s 打印方法的签名 注意要cd到 C:workspaceHelloWorldFromC2inclasses 传全类名

    通过反射 调用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);




  • 相关阅读:
    HashMap底层实现原理/HashMap与HashTable区别/HashMap与HashSet区别
    手动部署 Ceph Mimic 三节点
    Ceph 分布式存储架构解析与工作原理
    OpenStack 的单元测试
    OpenStack 虚拟机启动流程 UML 分析(内含 UML 源码)
    我非要捅穿这 Neutron(四)Open vSwitch in Neutron
    手动部署 OpenStack Rocky 双节点
    OpenStack Blazar 架构解析与功能实践
    基于 Open vSwitch 的 OpenFlow 实践
    OpenFlow/SDN 的缘起与发展
  • 原文地址:https://www.cnblogs.com/mukekeheart/p/5729611.html
Copyright © 2020-2023  润新知