使用NDk的场景:

1.某些方法,是使用C,C++本地代码实现的,然后,我想在Java中调用这些方法。这个时候,就需要使用到JNI技术。

应用NDK的时候,分两个部分,Java部分,JNI层部分,本地代码部分。

Java部分,看一个例子:

public class JNIActivity extends Activity {

  static{

    System.loadLibrary("myjni");
} public native String getMessage(); @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); TextView textView = new TextView(this);
textView.setText(getMessage()); setContentView(textView);
} @Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.jni, menu);
return true;
} @Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}

Java部分,要做的事情就是:1.声明要使用的本地方法,使用关键字native。2.加载包含实现该方法的库(在windows平台下是dll;在类Unix平台下是.so)。

JNI层部分,则应用了JNI部分的知识,比如:

#include <jni.h>
#include "include/HelloJNI.h" JNIEXPORT jstring JNICALL Java_com_mytest_JNIActivity_getMessage
(JNIEnv *env, jobject thisObj) {
return (*env)->NewStringUTF(env, "Hello from native code!");
}

用一个简单的例子说明NDK的开发步骤:

1.一个使用本地方法的Java类JNIActivity,声明使用C,C++代码实现的本地方法使用native关键字;载入动态库,此时动态库还没有生成。

结果如下:

public class JNIActivity extends Activity {

  static{

    System.loadLibrary("myjni");
} public native String getMessage(); @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); TextView textView = new TextView(this);
textView.setText(getMessage()); setContentView(textView);
} @Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.jni, menu);
return true;
} @Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}

2.在项目一级目录下创建jni文件夹;在jni文件夹下创建include文件夹。include文件夹,用来存放头文件。

3.使用javah生成头文件---静态函数注册,将java层调用的本地方法与JNI层实现的方法进行关联

在src目录下,使用命令:javah com.mytest.JNIActivity。

类JNIActivity.java使用了原生方法;JNIActivity.java存放在src目录下。

使用上述命令之后,在src目录下会有一个头文件:com_mytest_JNIActivity.h。

将该头文件,复制到jni/include目录下,修改名字为HelloJNI.h。

HelloJNI.h的内容:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_mytest_JNIActivity */ #ifndef _Included_com_mytest_JNIActivity
#define _Included_com_mytest_JNIActivity
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_mytest_JNIActivity
* Method: getMessage
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_mytest_JNIActivity_getMessage
(JNIEnv *, jobject); #ifdef __cplusplus
}
#endif
#endif

4.创建原生代码

用原生代码实现头文件(HelloJNI.h)中所声明的方法。创建HelloJNI.c,存放在jni目录下。

HelloJNI.c:

#include <jni.h>
#include "include/HelloJNI.h" JNIEXPORT jstring JNICALL Java_com_mytest_JNIActivity_getMessage
(JNIEnv *env, jobject thisObj) {
return (*env)->NewStringUTF(env, "Hello from native code!");
}

5.创建Android.mk

Android.mk文件,描述编译信息。

创建一个Android.mk文件,存放在jni目录下

Android.mk:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := myjni
LOCAL_SRC_FILES := HelloJNI.c include $(BUILD_SHARED_LIBRARY)

其中myjni,是一个动态库名称,它来自于java层代码,System.loadLibrary("myjni");。这个名字要与Java层中加载的动态库名称相同。

HelloJNI.c,是实现原生方法的源代码。

有关Android.mk更详细的内容,请参看Android官方文档。

6.编译

确保已经安装了NDK;并且把ndk-build对应的路径添加到系统的Path变量中。

在项目的一级目录,执行命令ndk-build。

如下:

这样就编译成功了。

7.运行

运行App。

总结:

NDK的使用中,关键就是,创建头文件,编写Android.mk。在实现原生方法的时候,就是应用JNI方面的知识了。

最新文章

  1. 在服务器上启用HTTPS的详细教程
  2. 打造理想的Windows 10 APP开发环境的5个步骤
  3. ReactiveCocoa中信号的使用
  4. OpenCV坐标体系的初步认识
  5. Django 1.10中文文档—第一个Django应用Part1
  6. EasyUI 两个日期比较
  7. Vmware(vmdk)虚拟机到hyperv(vhd)虚拟机转换
  8. 文本分布式表示(三):用gensim训练word2vec词向量
  9. 入坑C++之vs 新建C++项目
  10. dubbo 面试
  11. .net Json 反序列化时,属性带点
  12. jmeter的介绍和使用二
  13. python TypeError: &#39;int&#39; object is not callable 问题解决
  14. Spring日记_01 之基于maven的Spring环境搭建
  15. Redis 的 5 种数据结构
  16. thinkphp或者kohana 导入和读取文件
  17. iOS- Exception Type: 00000020:什么是看门狗机制
  18. Java API 各个包的内容解释
  19. qq空间相册下载
  20. wusir 线程间操作无效: 从不是创建控件“”的线程访问它 解决办法

热门文章

  1. M2迭代分数分配
  2. sigsuspend
  3. 显示系统中所有的socket信息
  4. 【转】log4j.properties文件的配置
  5. 钉钉 E应用 打开分享外链
  6. [计算机网络-应用层] P2P应用
  7. Shel脚本学习—反引号、单引号、双引号区别与联系
  8. 【刷题】BZOJ 3175 [Tjoi2013]攻击装置
  9. [WC2005]友好的生物
  10. 使用httpclient post请求中文乱码解决办法