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