《深入理解Android》学习笔记(一) ——— 初识JNI

1. JNI, Java Native Interface,即 Java本地调用。

作用:JNI层作为连接Java世界与Native世界的桥梁,使Java程序中函数可以调用Native(C/C++)编写的函数,Native(C/C++)程序中可以调用Java的函数。

2. Java要调用Native函数,需要完成以下两项工作:

(1)加载对应的JNI动态库。通常在Java类的static语句中调用System.loadLibrary方法动态加载JNI库。

(2)声明由关键字native修饰的函数。native为Java关键字,表示它由JNI层完成。

3. 注册JNI函数,即将Java层的native函数和JNI层对应的实现函数关联起来。注册方式有两种:

(1)静态注册:根据函数名来建立Java函数与JNI函数之间的关联关系。

步骤:i)先编写Java代码,然后生成编译生成.class文件。

ii)使用Java工具程序javah,如 javah -o output packagename.classname,生成一个名叫output.h的JNI层头文件,其中packagename.classname为Java代码编译后的class文件。在output.h中声明了对应的JNI层函数,只要实现里面的函数即可。

(2)动态注册:在JNI层代码中调用JNIEnv的RegisterNatives函数实现注册关联关系。

动态注册的时机:Java层通过System.loadLibrary()加载完JNI动态库后,会查找该库中的JNI_OnLoad函数,如果找到,就调用,因此动态注册的工作可以放在这个函数中执行。

4. JNIEnv

(1)JNIEnv是一个与线程相关的代表JNI环境的结构体,提供了一些JNI系统函数,通过这些函数可以:

  • 调用Java的函数。
  • 操作jobject对象等事情。

(2)JavaVM与JNIEnv的关系

整个进程只有一个JavaVM,在线程中通过JavaVM的AttachCurrentThread()函数,就可以得到该线程的JNIEnv结构体,从而可以在后台线程中回调Java函数了。在后台线程退出前,要调用JavaVM的DetachCurrentThread()函数来释放对应资源。

5. 垃圾回收

JNI的三种引用类型:

(1) Local Reference:本地引用。 JNI层函数中使用的非全局引用对象都是Local Reference,包括函数调用时传入的jobject和在JNI层函数中创建的jobject。一旦JNI层函数返回,jobject就可能被垃圾回收。

(2) Global Reference: 全局引用。这种对象若不主动释放,永远不会被垃圾回收。

(3) Weak Global Reference: 弱全局引用。在运行过程中有可能会被垃圾回收,在使用它之前,需要调用JNIEnv的IsSameObject判断它是否被回收。

由于Java层的对象有可能被垃圾回收了,若JNI层中将Java层的对象存为Local Reference,则有可能出现异常。所以,JNI层中要保存Java层的对象时,使用Global Reference,使用完之后进行释放。

时间: 2024-10-07 07:40:15

《深入理解Android》学习笔记(一) ——— 初识JNI的相关文章

udacity android学习笔记: lesson 3

udacity android学习笔记: lesson 3 作者:干货店打杂的 /titer1 /Archimedes 出处:https://code.csdn.net/titer1 联系:1307316一九六八 声明:本文采用以下协议进行授权: 自由转载-非商用-非衍生-保持署名|Creative Commons BY-NC-ND 3.0 ,转载请注明作者及出处. tips:https://code.csdn.net/titer1/pat_aha/blob/master/Markdown/an

android学习笔记--android启动过程之init.rc文件浅析

1.  init.rc文件结构文件位置:init.c  : /system/core/initinit.rc  : /system/core/rootdir 首先init.rc文件是以模块为单位的,每个模块里的内容都是一起执行的,模块分为3种类型:on.service.import.我们可以看下init.rc文件是怎么写的:1.import import /init.usb.rc import /init.${ro.hardware}.rc import /init.trace.rc 上面的内容

Android学习笔记(十五)——碎片的生命周期(附源码)

碎片的生命周期 点击下载源码 与活动类似,碎片具有自己的生命周期.理解了碎片的生命周期后,我们可以在碎片被销毁时正确地保存其实例,在碎片被重建时将其还原到前一个状态. 1.使用上一篇的项目Fragments,在Fragment1.java文件中添加如下代码: package net.zenail.Fragments; import android.app.Activity; import android.os.Bundle; import android.support.v4.app.Fragm

udacity android 学习笔记: lesson 4 part b

udacity android 学习笔记: lesson 4 part b 作者:干货店打杂的 /titer1 /Archimedes 出处:https://code.csdn.net/titer1 联系:1307316一九六八 声明:本文採用下面协议进行授权: 自由转载-非商用-非衍生-保持署名|Creative Commons BY-NC-ND 3.0 ,转载请注明作者及出处. tips:https://code.csdn.net/titer1/pat_aha/blob/master/Mar

Android 学习笔记(二七):Menu

Menu由两种形式,Option menu和Context menu.前者是按下设备的Menu硬按钮弹出,后者是长按widget弹出. Option Menu 当我们按下Menu的硬件按钮时,Option Menu将被触发显示,最多可以显示6个选项的icon菜单,如果选项多于6个,第6个选项显示为“More“,点击可以进入扩展菜单.我们将在Android学习笔记(十一):Activity-ListView的例子一的基础上来学习Option Menu,也就是一个基于activity的菜单. 在这个

六、Android学习笔记_JNI_c调用java代码

1.编写native方法(java2c)和非native方法(c2java): package com.example.provider; public class CallbackJava { // C调用java空方法 public void helloFromJava() { System.out.println("hello from java"); } // C调用java中的带两个int参数的方法 public int Add(int x, int y) { int res

七、Android学习笔记_JNI hello world

1.需要准备的工具,eclipse,cdt(c++)插件,cygwin(unix)和 android ndk. 在cygwin的etc目录下将ndk的路径引入到profile文件中,可以在cygwin的任何目录都可以访问到ndk,不同的ndk路径PATH的写法不同. : ${ORIGINAL_PATH=${PATH}} if [ ${CYGWIN_NOWINPATH-addwinpath} = "addwinpath" ] ; then PATH="/usr/local/bi

[Android学习笔记]ListView中含有Button导致无法响应onItemClick回调的解决办法

转自:http://www.cnblogs.com/eyu8874521/archive/2012/10/17/2727882.html 问题描述: 当ListView的Item中的控件只是一些展示类控件时(比如TextView),注册ListView的监听setOnItemClickListener之后,当点击Item时候会触发onItemClick回调. 但是,当Item中存在Button(继承于Button)的控件时,onItemClick回调不会被触发. 解决方案: 在Item的布局文件

Android学习笔记_JNI hello world

1.需要准备的工具,eclipse,cdt(c++)插件,cygwin(unix)和 android ndk. 2.开发步骤: a.创建一个android工程 b.JAVA代码中写声明 native 方法 public native String helloFromJNI(); 通过javah 包名.类名生成jni的方法签名 c. 创建jni目录,编写c代码,方法名字要对应.或者将生成的签名文件拷贝到jni目录,然后在c代码中引入. d.编写Android.mk文件 e.Ndk编译生成动态库(