您的位置:首页 > 移动开发 > Android开发

android下JNI开发--02

2015-10-18 23:53 363 查看

c基本语法

#include import stdlib.h stdio.h

system

C基本数据类型 C没有byte boolean 0非0表示false true

char c1字节 long 4字节

signed unsigned 修饰整形变量 有符号无符号

sizeof 取出类型所占字节数

C 输出函数 printf (“输出的内容+占位符”,变量)

占位符跟变量类型匹配

C的字符串 字符数组 {手动加上结束符 ‘\0’} char cstr[] = “abcd”;

char* cstr = “abcd”; “%s”

输入函数 scanf(“占位符”,内存地址); &取地址符

内存地址 计算机中一般用16进制数来表示内存地址

指针 int* p; int 变量来保存一个地址(32位系统)

int i; int* p = &i; p &p *p

野指针 指针类型要匹配 int* 指向int变量地址

值传递 引用传递

指针和数组之间的关系

多级指针

栈内存 堆内存

静态内存分配 malloc free realloc

结构体 struct Student

结构体长度 大于等于所有变量长度的和 是最大的那个变量的长度的整数倍

函数指针 返回值类型(*指针名字)(参数)

结构体的指针 (*stup).age stup->age;

联合体 枚举

typedef

交叉编译

在一个平台下编译出另一个平台下可以运行的本地代码

cpu平台 x86 arm mips

操作系统平台 windows linux mac os unix

原理 在一个平台下模拟另一个平台的特点去编译本地代码

NDK native develop kit SDK

NDK 目录结构

docs 帮助文档

platforms 根据不同的android版本号分文件夹

include 头文件

lib 谷歌提供的做jni开发可以用到的库

samples 谷歌提供的样例工程 供参考

sourcese jni相关源代码

build->tools .sh文件 linux平台下的批处理文件 交叉编译时会自动调用

ndk-build.cmd

CDT 高亮C的关键字 代码提示

JNIHElloWORLD

jni开发流程

java native interface

①写java代码 声明本地方法 用关键字 native 本地方法不用实现 具体的实现在C代码中

② 创建jni目录 在项目的根目录下创建

③ 创建Android.mk linux下的makefile文件

向编译系统描述一下 我要编译的代码在哪儿 生成一个叫什么名字的文件

* LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := hello   #System.loadlibrary("hello")
LOCAL_SRC_FILES := hello.c #.c源文件的名字

include $(BUILD_SHARED_LIBRARY)


④ 创建C源码 本地函数名的命名规则 本地函数命名规则 Java_包名类名本地方法名

//JNIEnv* env env 是JNIEnv 的一级指针 env就是结构体 JNINativeInterface的二级指针

//(**env).函数指针 (*env)->函数指针

//JNIEnv 是结构体 JNINativeInterface的一级指针

//结构体 JNINativeInterface定义了大量的函数指针

//jobject thiz 那个类调用的本地函数 这个thiz 就是这个类的对象 在这个例子中 thiz 指的就是Mainactivity的对象

必须导入 jni.h头文件

⑤ 调用ndk-build编译源代码 到项目根目录下运行ndk-build

⑥ java代码中 调用System.loadlibrary(“”)

jni开发常见错误

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

本地方法名写错

避免写错 javah生成头文件

jdk1.7以上 到项目/src目录下去运行 生成的头文件就在src目录下

jdk1.6 到项目/bin/classes 目录下运行javah 生成的头文件在 /bin/classes去找

javah +声明本地方法的类的全类名

忘记加载动态链接库 没有调用

System.loadLibrary(“hello”);

找动态链接库返回空 java.lang.UnsatisfiedLinkError: ….. findLibrary returned null

System.loadLibrary(“hello”); 动态链接库的名字写错

没有编译出对应平台的.so文件 需要手动创建 Application.mk 指定

APP_ABI := armeabi x86

APP_PLATFORM := android-14

简便开发流程

①写java代码 声明本地方法 用关键字 native 本地方法不用实现 具体的实现在C代码中

② 添加本地支持 右键单击项目->android tools->add native surrport 添动态链接库的名字

如果发现finish不能点击 需要配置NDK目录(每一个工作空间只需要配置一次NDK目录)

window->preferences->android->ndk 指定一下ndk解压的目录

③ jni目录创建好之后 会有.cpp的源文件 Android.mk如果需要些.c文件 修改扩展名,修改Android.mk, Application.mk 需要手动创建 如果是x86的模拟器 需要创建Application.mk

④ javah生成头文件

⑤ 解决CDT插件报错的问题 右键单击项目->properties->c/c++ general->paths and symbols->includes选项卡->add…->File system->找到ndk解压目录 ->platforms文件夹 找到项目支持的最小版本文件夹下的include目录 指定进来

⑥ 编写C代码 运行之前不要忘记 java中System.loadLibrary(“hello”);

C代码中打log

Android.mk文件增加以下内容
LOCAL_LDLIBS += -llog
# 加载android提供的.so库 如果加载liblog.so
#LDLIBS load librarys的意思  -l就是加载的意思
C代码中增加以下内容
#include <android/log.h>
#define 是C的宏定义 可以给 字符串 和函数起别名
#define LOG_TAG "System.out"
//给__android_log_print函数起别名 第一参数 有限及 第二个参数打log的TAG
//LOGD 就是打印优先级是DEBUG的LOG 用法跟printf一样
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)


C回调java

①拿到字节码对象

// jclass (FindClass)(JNIEnv, const char*);

//第二个参数 要回调的java类的路径com/itheima/Ccallback/JNI

②拿到方法

//第二个参数 刚创建的字节码对象

//第三个参数 要回调的java方法名 第四个参数 方法签名

//如何获取方法签名 javap命令 项目/bin/classes目录下运行javap -s 要获取方法签名的类的全类名

//jmethodID (GetMethodID)(JNIEnv, jclass, const char*, const char*);

③通过字节码对象获取到java对象(可选)

//当回调方法跟本地方法没有声明到一个类中就要创建java对象

//jobject (AllocObject)(JNIEnv, jclass); jclass 刚创建的字节码对象

//需要注意的是 如果回调的方法在Activity中 不能自己new activity

④调用方法

//void (Call***Method)(JNIEnv, jobject, jmethodID, …);

//根据返回值的类型选择不同的函数

//第二个参数 回调的方法所在的java对象 第三个参数刚创建的java方法对应的jmethodID

//可选的参数 回调方法要传的数据
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: