android底层接口,1-安卓底层--基础

1-安卓底层--基础

先看看代码: java 调用 C/C++ 代码

1.TestJni.java

public class TestJni{

static{

System.loadLibrary("xxx"); //加载 libxxx.so 库文件

}

public native void hello(); //本地方法,在so文件里实现

public static void main (String [] args){

TestJni d = new TestJni();

d.hello(); //调用库文件里面的hello方法

}

}

2.编译java程序 javac TestJni.java 生成 TestJni.class

3.通过javah生成jni接口 javah TestJni 生成 TestJni.h

4.新建xxx.c 文件 然后实现接口

#include

JNIEXPORT void JNICALL Java_TestJni_hello(JNIEnv * env, jobject obj){

printf("hello world\n");

}

5.编译成so库文件 ( linux 动态库命名规则 lib + 库名 + .so window 库名+.dll )

gcc -shared -fPIC xxx.c -o libxxx.so -I /usr/lib/jvm/java-7-openjdk-amd64/include/

-I 指定头文件的路径 -L 指定库的路径 -l更上名字 -lm -lsqlite3

6.指定动态库的路径 export LD_LIBRARY_PATH=:

7.运行java TestJni

* jni.h 在编译android源码时要安装jdk 5.0之前 直接下载甲骨文的jdk 5.0之后 要安装openjdk (sudo apt-get install openjdk+版本)注意 android 和jdk的版本有对应关系(android 官网)

* Java_TestJni_hello 接口的名字 命名规则 Java_+类名_+本地方法名 接口的返回值和方法的返回值一致

* JNIEnv jni总管 他是一个函数指针数组的首地址 成员为函数指针 jobject java对象

第二种

第二种方式的jni实现

vi /usr/lib/jvm/java-7-openjdk-amd64/include/linux/jni.h

1. 完成入口函数

1944 JNIEXPORT jint JNICALL

1945 JNI_OnLoad(JavaVM *vm, void *reserved);

2. 在入口函数里面实现 一下三步

2.1 获得java虚拟机环境

jint (JNICALL *GetEnv)(JavaVM *vm, void **penv, jint version);

2.2 找到先关的类

jclass (JNICALL *FindClass)

226 (JNIEnv *env, const char *name);

* (*env)->FindClass(env, "java/lang/String")

2.3 注册

720 jint (JNICALL *RegisterNatives)

721 (JNIEnv *env, jclass clazz, const JNINativeMethod *methods,jint nMethods);

完成 JNINativeMethod 这个结构体 作用是本地方法和本地函数的映射关系

180 typedef struct {

181 char *name; //本地方法的名字

182 char *signature; // 本地方法的签名

183 void *fnPtr; // 相对应的本地函数

184 } JNINativeMethod;

函数签名通常是以下结构:

返回值 fun(参数1,参数2,参数3);

其对应的Jni方法签名格式为:(参数1参数2参数3) 返回值

注意:

函数名,在Jni中没有体现出来

参数列表相挨着,中间没有逗号,没有空格

返回值出现在()后面

如果参数是引用类型,那么参数应该为:L类型;

第一种jni 和第二种jni 实现方式有何不一样

第二种有入口函数 可以对jni 做一些初始化工作

第二种方式是通过 jninativemethod 这个结构体来匹配的

第一种是靠名字匹配的

实现接口文件

1 实现JNI_OnLoad 函数

2 是在入口函数里面获得jvm 环境变量 通过 GetEnv 这个函数

3 找类 findclass();

4 注册 RegisterNatives method 这个结构体

5 实现 method 这个结构体 让java的本地方法 和 jni的本地函数绑定在一起

写法

TestJni.java

public class TestJni{

static {

System.loadLibrary("native");

}

public native int hello(int i,char j);

public static void main (String [] args){

TestJni d = new TestJni();

d.hello(12,'r');

}

}

native.c

#include

jint Jhello(JNIEnv *env,jobject obj,jint i,jchar j){

printf("%d\t%c\n",i,j);

}

//函数数组 ,

//参数1 java 里写的本地方法名

//参数2 签名(看下面的图)头文件里自动生成

//参数3 调用的函数的指针

JNINativeMethod method[] = {

"hello","(IC)I",(void *)Jhello,

};

JNIEXPORT jint JNICALL

JNI_OnLoad(JavaVM *vm, void *reserved)

{

JNIEnv *env;

jclass cls;

if((*vm) -> GetEnv(vm,(void **)&env,JNI_VERSION_1_4))

return JNI_ERR;

cls = (*env) ->FindClass(env,"TestJni");

if(cls == NULL) return JNI_ERR;

//注册函数

(*env) -> RegisterNatives(env,cls,method,sizeof(method)/sizeof(JNINativeMethod));

return JNI_VERSION_1_4;

}

签名类型

408471cdbdd4

签名类型.PNG

两者之间的数据类型

408471cdbdd4

两者之间的数据类型.PNG

java传数组

TestJni.java

public class TestJni{

static {

System.loadLibrary("native");

}

public native int hello(int []arr,int len);

public static void main (String [] args){

int []ibo = {12,13,14,15};

TestJni d = new TestJni();

System.out.println(d.hello(ibo,ibo.length));

}

}

native.c

#include

jint Jhello(JNIEnv *env,jobject obj,jintArray arr,jint num){

jint *carr;

jint i, sum = 0;

carr = (*env)->GetIntArrayElements(env, arr, NULL);

if (carr == NULL)return 0;

for (i=0; i

(*env)->ReleaseIntArrayElements(env, arr, carr, 0);

return sum;

}

JNINativeMethod method[] = {

(char *)"hello",(char *)"([II)I",(void *)Jhello,

};

JNIEXPORT jint JNICALL

JNI_OnLoad(JavaVM *jvm, void *reserved){

JNIEnv *env;

jclass cls;

if ((*jvm)->GetEnv(jvm, (void **)&env, JNI_VERSION_1_2)) {

return JNI_ERR;

}

cls = (*env)->FindClass(env, "TestJni");

if (cls == NULL) return JNI_ERR;

(*env) -> RegisterNatives(env,cls,method,sizeof(method)/sizeof(JNINativeMethod));

return JNI_VERSION_1_2;

}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值