Android系统JNI的实现方式

All rights reserved

JNI(Java Native Interface)定义了一种Java代码调用C或者C++代码等其它代码的方式。

在Android系统中,JNI通过JNINativeMethod结构体进行描写叙述,该结构体定义于jni.h,例如以下所看到的:

  1. typedef struct {
  2. const char* name;
  3. const char* signature;
  4. void* fnPtr;
  5. } JNINativeMethod;

第一个參数name:是Java代码中的函数名。

第二个參数signature:用于描写叙述函数的參数和返回值。

第三个參数fnPtr:C代码中函数的指针。

当中,第二个參数为一个描写叙述函数參数和返回值的字符串,字符串的格式例如以下:

(XX..)X

X的取值和定义例如以下所看到的:

字符

Java类型

C类型

V

void

void

Z

jboolean

unsigned char

B

jbyte

signed char

C

jchar

unsigned short

S

jshort

short

I

jint

int

J

jlong

long

F

jfloat

float

D

jdouble

double

另外,从jni.h中对于变量类型的定义中也能够看到这些字符的意义,例如以下所看到的:

  1. typedef unsigned char jboolean; /* unsigned 8 bits */
  2. typedef signed char jbyte; /* signed 8 bits */
  3. typedef unsigned short jchar; /* unsigned 16 bits */
  4. typedef short jshort; /* signed 16 bits */
  5. typedef int jint; /* signed 32 bits */
  6. typedef long long jlong; /* signed 64 bits */
  7. typedef float jfloat; /* 32-bit IEEE 754 */
  8. typedef double jdouble; /* 64-bit IEEE 754 */
  9.  
  10. typedef union jvalue {
  11. jboolean z;
  12. jbyte b;
  13. jchar c;
  14. jshort s;
  15. jint i;
  16. jlong j;
  17. jfloat f;
  18. jdouble d;
  19. jobject l;
  20. } jvalue;

比如,为一个驱动加入HAL层,并创建JNI层。仅就JNI层而言,创建frameworks/base/services/jni/com_android_server_DemoService.cpp文件,该文件里用于描写叙述JNI接口的代码例如以下所看到的:

  1. static const JNINativeMethod method_table[] = {
  2. {"init_native", "()I", (void*)demo_init},
  3. {"setVal_native", "(II)V", (void*)demo_setVal},
  4. {"getVal_native", "(I)I", (void*)demo_getVal},
  5. };

当中“(II)V”,表示函数的有两个整形參数,返回值为void。

注意:由參数二指定的函数參数和返回值类型一定要和C函数的參数和返回值保持一致,否则尽管编译可以通过,但在Android系统载入过程中,会报例如以下所看到的的错误,导致Android系统无法正常执行。

  1. E/dalvikvm( 1737): ERROR: couldn't find native method
  2. E/dalvikvm( 1737): Requested: Lcom/android/server/DemoService;.init_native:()Z
  3. E/dalvikvm( 1737): Candidate: Lcom/android/server/DemoService;.init_native:()I
  4. E/JNIHelp ( 1737): RegisterNatives failed for 'com/android/server/DemoService', aborting
  5. F/libc ( 1737): Fatal signal 11 (SIGSEGV) at 0xdeadbaad (code=1), thread 1737 (system_server)

以上错误通发生在frameworks/base/services/jni/onload.cpp文件里的JNI_OnLoad()函数中,例如以下所看到的:

  1. extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved)
  2. {
  3. JNIEnv* env = NULL;
  4. jint result = -1;
  5.  
  6. if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
  7. ALOGE("GetEnv failed!");
  8. return result;
  9. }
  10. ALOG_ASSERT(env, "Could not retrieve the env!");
  11. ……
  12. <strong>register_android_server_DemoService(env);</strong>
  13. ……
  14. return JNI_VERSION_1_4;
  15. }

另外,ProGuard对程序的优化也可能导致上述执行错误的发生。此时,能够在makefile文件里加入“LOCAL_PROGUARD_ENABLED:=disabled”宏来关闭ProGuard的优化。

关于ProGuard,能够參考其官方站点:http://proguard.sourceforge.net/

ProGuard是一个免费的Java类文件压缩器、优化器、混淆器和预校验器。它会检測并删除没实用到的类、域、方法以及属性。它最大限度的优化字节码而且删除没用的指令。它用非常短的没有意义的名字对剩余的类、域和方法进行重命名。最后,它对处理过的代码进行预校验。

ProGuard的一些用途例如以下:

A.为了更小的代码档案、更快的网络传输、更快的载入速度和更小的内存占用创建更紧凑的代码;

B.使程序和库难于进行反向project;

C.列出死代码,这样就能将其删除;

D.为Java 6或更高的版本号对存在的类文件进行重定位和预校验,以充分利用其高速载入类的性能。

Android系统JNI的实现方式的更多相关文章

  1. Android之 看“马达”如何贯通Android系统 (从硬件设计 --> 驱动 --> HAL --> JNI --> Framework --> Application)

    在Android 2.3(Gingerbread) 系统的时候,我写过一篇关于“Android 震动马达系统“的文章,当时的Linux内核还是2.6版本的.写那篇文章的目的,是想彻底的了解从硬件到驱动 ...

  2. 深入浅出 - Android系统移植与平台开发(十二)- Android JNI机制

    第五章.JNI机制 4.1 JNI概述 由前面基础知识可知,Android的应用层由Java语言编写,Framework框架层则是由Java代码与C/C++语言实现,之所以由两种不同的语言组合开发框架 ...

  3. Android系统关机或几种方式重启

    ---------------------------------------------------------------------------------------------------- ...

  4. OpenCV4Android释疑: 透析Android以JNI调OpenCV的三种方式(让OpenCVManager永不困扰)

    OpenCV4Android释疑: 透析Android以JNI调OpenCV的三种方式(让OpenCVManager永不困扰) 前文曾详细探讨了关于OpenCV的使用,原本以为天下已太平.但不断有人反 ...

  5. Android系统关机或重启的几种实现方式

    前阵子工作上遇到一些关于Android系统关机或重启的系统修改,于是,做了一些尝试,也搜集了一下资料,现在整理一下,做一些总结,方便学习或者日后工作的需要. 默认的SDK并没有提供应用开发者直接的An ...

  6. Android系统固件定制方式

    target_product.mkAndroid系统在构建关于某种产品的固件时,一般会根据特定于该产品的具体target_product.mk来配置生成整个Android系统./target_prod ...

  7. Android 通过JNI实现守护进程,使得Service服务不被杀死

    来自: http://finalshares.com/read-7306 转载请注明出处: http://blog.csdn.net/yyh352091626/article/details/5054 ...

  8. 修改Android系统属性SystemProperties.set("sys.powerctl", "shutdown")关机分析

    简介: 从之前的博文中我们提到过,关机流程中最后是通过修改Android属性进行关机操作(SystemProperties.java通过JNI调用访问系统属性),当然我们也可以通过adb命令修改And ...

  9. android的JNI 、 NDK 学习!

    转载的! Java Native Interface (JNI)标准是java平台的一部分,它允许Java代码和其他语言写的代码进行交互.JNI 是本地编程接口,它使得在 Java 虚拟机 (VM) ...

随机推荐

  1. this指针与function变量--this究竟指向哪里?

    参考文章:<深入浅出 JavaScript 中的 this> http://www.ibm.com/developerworks/cn/web/1207_wangqf_jsthis/ Ja ...

  2. MSI文件静默安装

    以.net4为例,以下命令为静默安装: dotNetFx40_Full_x86_x64.exe /q /norestart /ChainingPackage FullX64Bootstrapper / ...

  3. 《转》精巧好用的DelayQueue

    该文章转自:http://www.cnblogs.com/jobs/archive/2007/04/27/730255.html 我们谈一下实际的场景吧.我们在开发中,有如下场景 a) 关闭空闲连接. ...

  4. Cortex-M3学习日志(三)-- 外部中断0

    无论是哪款单片机应该都有对应的中断的功能,中断在嵌入式系统的地位毋庸置疑.LPC1768微处理器包括4个外部中断,分别是EINT0.EINT1.EINT2.EINT3对应的引脚分别是P2.10~P2. ...

  5. Xcode 真机测试破解方法(转加修改)xcode 4.3 通过

    Xcode 真机测试破解方法(转加修改)xcode 4.3 通过 生成本机证书 应用程序->实用工具->钥匙串访问 菜单:钥匙串访问->证书助理->创建证书, 然后按以下图片顺 ...

  6. NOI2012 Day2

    NOI2012 Day2 迷失游乐园 题目描述:给出一个\(n\)个点的图,边数为\(n-1\)或\(n\).从某个点出发,每次等概率地随机选一个相连的并且没有经过过的点,直到不能走为止,问期望路径长 ...

  7. oracle job 定时执行 存储过程

    oracle job 定时执行 存储过程   一:简单测试job的创建过程案例: 1,先创建一张JOB_TEST表,字段为a 日期格式 SQL> create table JOB_TEST(a ...

  8. Socks5协议中文文档

    译者:Radeon(Radeon bise@cmmail.com) 译文公布时间:2001-6-18 文件夹 1.介绍 2.现有的协议 3.基于TCP协议的客户 4.请求 5.地址 6.应答 7.基于 ...

  9. 2013 多校联合 F Magic Ball Game (hdu 4605)

    http://acm.hdu.edu.cn/showproblem.php?pid=4605 Magic Ball Game Time Limit: 10000/5000 MS (Java/Other ...

  10. SQL练习之不反复执行相同的计算

    下面是Demo所需要的代码: CREATE TABLE Fee ( Income ,), overhead ,) ) ,) ,) ,) ,) ,) ,) 现在有一个报表系统,需要根据Fee表获得以下数 ...