Android NDK 开发学习

原理:

Android NDK 是一系列工具,允许 Android 应用程序开发者嵌入从 C、C++源代码文件编译来的本地机器代码到各自的应用软件包中。NDK 集成了交叉编译器,可以把你用 C、C++书写的代码,编译为.so 格式的文件。

 在 Android 程序当中可以用 Java 语言(JNI)调用这些代码。并可以自动地将 so 和 Java 应用一起打包生成 apk,极大地减轻了开发人员的打包工作。

NDK 的功能

Android 虚拟机允许应用程序源代码通过 JNI 调用本地代码实现的方法。在 Java 代码中声明本地方法必须有"native"标识符,native 修饰的方法,在 Java 代码中只作为声明存在。例如:  native byte[] loadFile(String filePath);

必须提供一个包含这些方法实现的本地共享库,该共享库将会打包到你的应用程序的.apk 文件中。这个共享库是根据标准的 Unix 的规定来命名,像 lib<something>.so,并且应包含标准 JNI 调用点。例如:libFileLoader.so

在调用本地方法前,必须首先装载含有该方法的本地库. 如 HelloWorld.java 中所示,置于 static 块中,在 Java VM 初始化一个类时,首先执行这部分代码,这可保证调用本地方法前,装载了本地库。例如,在应用程序的开始加载它,只需将以下内容添加到应用程序的源代码中:

static {
System.loadLibrary("FileLoader");                                                  注意:在这里,您不需要使用前缀'lib'和后缀'.so'。
}      

Java 通过 JNI 机制和 C/C++沟通的具体步骤:

  1. 编写包含 native 本地方法的 Java 类。
  2. 通过 javah 工具生成 C/C++语言的头文件。
  3. 使用 C/C++语言实现的头语言。
  4. 使用交叉编译工具对 C/C++本地代码进行编译,最后通过链接生成*.so 可执行的 C/C++库。
  5. 实际执行 Java 代码去和本地 C/C++代码相互勾通。
源码分析:

HelloJniActivity.java

button.setOnClickListener(new View.OnClickListener() {//添加按钮事件监听与处理
public void onClick(View v) {
// TODO Auto-generated method stub 
String result = StringFromJNI();   //调用 jni 函数
mTextView.setText(result);
}
    });
}
/*  添加函数声明,告诉编译和链接器该方法在本地代码中实现 */
public native String StringFromJNI();
/*  加载 JNI 代码编译生成的共享库 */
static {
System.loadLibrary("hello -jni");
}
}
在通过布局文件在 Activity 中,添加一个按钮,并添加一个按钮事件处理。在按钮的事件处理函数,调用本地方法 StringFromJNI。

main.xml

hello-jni.c

#include <string.h>
#include <jni.h>
/* This is a trivial JNI example where we use a native method
* to return a new VM String. See the corresponding Java source
* file located at:
*/
jstring
Java_com_ndk_hellojni_HelloJniActivity_StringFromJNI( JNIEnv* env,jobject thiz )
{
return (*env)->NewStringUTF(env, "Hello from JNI !");
}
Jni 函数命名规则:
Java_pacakege_class_mathod 形式来命名,参数 JNIEnv*, jobject 是所有 jni 函数必有的两个参数,分别表示 Jni 环境和对应的 java 类(或对象)本身。
JNIEnv*内部包含一个 Pointer,  Pointer 指向 Dalvik 的 Java VM 对象的 Fanction Table,JNIenv*关于程序执行环境的从多函数正是来源于 Dalvik 虚拟机。Android 中每当一个 Java 线程第一次调用本地C/C++代码时, Dalvik 虚拟机实例会为该 Java 线程产生一个 JNIEnv*的指针。  Java 每条线程在和 C/C++相互调用时,JNIEnv*是相互独立的,互不干扰,这是提升并发执行时的安全性。当本地的 C/C++代码相获得当前线程所要使用的 JNIEnv 时,可以使用 Dalivk VM 对象的 Java VM* jvm->GetEnv()方法,该方法即会返回当前线程所在的 JNIEnv*。

Android.mk

LOCAL_PATH := $(call my -dir)    #当前路径
include $(CLEAR_VARS)         #清除变量
LOCAL_MODULE := hello -jni
LOCAL_SRC_FILES := hello-jni.c  #源文件路径
include $(BUILD_SHARED_LIBRARY)    #编译生成一个名为 lib.*.so 的共享库 

Android.mk 是 JNI 代码的 Makefile 文件。 hello-jni 为生成共享库名。编译成功后会 libs/armeabi/目录下生成 libled-jni.so 库文件。                                                                                     











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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值