使用NDk的场景:

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

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

Java部分,看一个例子:

  1. public class JNIActivity extends Activity {
  2.  
  3. static{
  4.  
  5. System.loadLibrary("myjni");
  6. }
  7.  
  8. public native String getMessage();
  9.  
  10. @Override
  11. protected void onCreate(Bundle savedInstanceState) {
  12. super.onCreate(savedInstanceState);
  13.  
  14. TextView textView = new TextView(this);
  15. textView.setText(getMessage());
  16.  
  17. setContentView(textView);
  18. }
  19.  
  20. @Override
  21. public boolean onCreateOptionsMenu(Menu menu) {
  22. // Inflate the menu; this adds items to the action bar if it is present.
  23. getMenuInflater().inflate(R.menu.jni, menu);
  24. return true;
  25. }
  26.  
  27. @Override
  28. public boolean onOptionsItemSelected(MenuItem item) {
  29. // Handle action bar item clicks here. The action bar will
  30. // automatically handle clicks on the Home/Up button, so long
  31. // as you specify a parent activity in AndroidManifest.xml.
  32. int id = item.getItemId();
  33. if (id == R.id.action_settings) {
  34. return true;
  35. }
  36. return super.onOptionsItemSelected(item);
  37. }
  38. }

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

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

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

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

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

结果如下:

  1. public class JNIActivity extends Activity {
  2.  
  3. static{
  4.  
  5. System.loadLibrary("myjni");
  6. }
  7.  
  8. public native String getMessage();
  9.  
  10. @Override
  11. protected void onCreate(Bundle savedInstanceState) {
  12. super.onCreate(savedInstanceState);
  13.  
  14. TextView textView = new TextView(this);
  15. textView.setText(getMessage());
  16.  
  17. setContentView(textView);
  18. }
  19.  
  20. @Override
  21. public boolean onCreateOptionsMenu(Menu menu) {
  22. // Inflate the menu; this adds items to the action bar if it is present.
  23. getMenuInflater().inflate(R.menu.jni, menu);
  24. return true;
  25. }
  26.  
  27. @Override
  28. public boolean onOptionsItemSelected(MenuItem item) {
  29. // Handle action bar item clicks here. The action bar will
  30. // automatically handle clicks on the Home/Up button, so long
  31. // as you specify a parent activity in AndroidManifest.xml.
  32. int id = item.getItemId();
  33. if (id == R.id.action_settings) {
  34. return true;
  35. }
  36. return super.onOptionsItemSelected(item);
  37. }
  38. }

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的内容:

  1. /* DO NOT EDIT THIS FILE - it is machine generated */
  2. #include <jni.h>
  3. /* Header for class com_mytest_JNIActivity */
  4.  
  5. #ifndef _Included_com_mytest_JNIActivity
  6. #define _Included_com_mytest_JNIActivity
  7. #ifdef __cplusplus
  8. extern "C" {
  9. #endif
  10. /*
  11. * Class: com_mytest_JNIActivity
  12. * Method: getMessage
  13. * Signature: ()Ljava/lang/String;
  14. */
  15. JNIEXPORT jstring JNICALL Java_com_mytest_JNIActivity_getMessage
  16. (JNIEnv *, jobject);
  17.  
  18. #ifdef __cplusplus
  19. }
  20. #endif
  21. #endif

4.创建原生代码

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

HelloJNI.c:

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

5.创建Android.mk

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

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

Android.mk:

  1. LOCAL_PATH := $(call my-dir)
  2.  
  3. include $(CLEAR_VARS)
  4.  
  5. LOCAL_MODULE := myjni
  6. LOCAL_SRC_FILES := HelloJNI.c
  7.  
  8. 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方面的知识了。

NDK---使用,开发步骤的更多相关文章

  1. Android(java)学习笔记259:JNI之NDK开发步骤

    1. NDK开发步骤(回忆一下HelloWorld案例): (1)创建工程 (2)定义native方法 (3)创建jni文件夹 (4)创建c源文件放到jni文件夹 (5)拷贝jni.h头文件到jni目 ...

  2. Android(java)学习笔记203:JNI之NDK开发步骤

    1. NDK开发步骤(回忆一下HelloWorld案例): (1)创建工程 (2)定义native方法 (3)创建jni文件夹 (4)创建c源文件放到jni文件夹 (5)拷贝jni.h头文件到jni目 ...

  3. NDK 的开发流程

    1.NDK开发所需要的工具 windows 需要在windows下的环境 把c代码打包成 手机能用的函数库 首先模拟手机的环境 1 NDK .sh linux 批处理文件 .bat windows 头 ...

  4. Android(java)学习笔记262:JNI之工具快速开发步骤

    下面通过一个案例说明一下,利用工具jni快速开发步骤 1.新建一个Android工程,命名为"03_对int数组加1",如下: 2. 在MainActivity.java中对add ...

  5. [Android] AndroidStudio + JNI(NDK)开发相关总结

    1.官方推荐JNI构建方案 从Android studio 2.2 开始,Google推荐的JNI开发构建工具是CMake而不是NDK,参考官方文档:https://developer.android ...

  6. Android(java)学习笔记206:JNI之工具快速开发步骤

    下面通过一个案例说明一下,利用工具jni快速开发步骤 1.新建一个Android工程,命名为"03_对int数组加1",如下: 2. 在MainActivity.java中对add ...

  7. AndroidStudio如何配置NDK/JNI开发环境

    参考文章: http://www.th7.cn/Program/Android/201509/550864.shtml http://www.open-open.com/lib/view/open14 ...

  8. 【OpenWRT】【RT5350】【三】MakeFile文件编写规则和OpenWRT驱动开发步骤

    一.Makefile文件编写 http://www.cnblogs.com/majiangjiang/articles/3218002.html 可以看下上面的博客,总结的比较全了,在此不再复述 二. ...

  9. iOS应用内付费(IAP)开发步骤列表

    iOS应用内付费(IAP)开发步骤列表 前两天和服务端同事一起,完成了应用内付费(以下简称IAP, In app purchase)的开发工作.步骤繁多,在此把开发步骤列表整理如下.因为只是步骤列表, ...

随机推荐

  1. k邻近算法理解及代码实现

    github:代码实现 本文算法均使用python3实现 1 KNN   KNN(k-nearest neighbor, k近邻法),故名思议,是根据最近的 $ k $ 个邻居来判断未知点属于哪个类别 ...

  2. Sparsity Invariant CNNs

    文章链接 Abstract 本文研究稀疏输入下的卷积神经网络,并将其应用于稀疏的激光扫描数据的深度信息完成实验.首先,我们表明,即使当丢失数据的位置提供给网络时,传统卷积网络在应用于稀疏数据时性能也很 ...

  3. 使用协程(gevent)实现请求

    协程,又称微线程.英文名Coroutine. 协程最大的优势就是协程极高的执行效率.因为子程序切换不是线程切换,而是由程序自身控制,因此,没有线程切换的开销,和多线程比,线程数量越多,协程的性能优势就 ...

  4. CEntOS6.5从启动界面直接进入命令行界面

    ctrl + alt + F1 ctrl + alt + F2 ctrl + alt + F3 ctrl + alt + F4 ctrl + alt + F5 ctrl + alt + F6 同时按下 ...

  5. 特殊符号存入mysql数据库时报错:Incorrect string value: '\xF0\x9F\x98\x84\xF0\x9F的解决方法

    问题描述:从新浪微博抓取消息保存到MySQL数据中,对应数据库字段为varchar,字符编码utf-8.部分插入成功,部分插入失败,报错如标题. 在网上查询,有人说是编码问题,建议修改编码格式,比如改 ...

  6. SQL SERVER 存储过程中SELECT 返回值如何赋值给变量

    今天在处理一个问题时,使用到一个存储过程,是用于更新并获取最新ID的.在使用过程中,需要获取到这个ID并赋值给变量,结果用EXEC @ID = 存储过程的方式获取失败了.具体情况如下: 为了还原整个情 ...

  7. Jetty与Tomcat综合比较

    Jetty基本架构 Jetty目前的是一个比较被看好的 Servlet 引擎,它的架构比较简单,也是一个可扩展性和非常灵活的应用服务器.它有一个基本数据模型,这个数据模型就是 Handler(处理器) ...

  8. 用select (多路复用)模拟一个 socket server

    需求:用select (多路复用)模拟一个 socket server.可以接收多并发. 1. 一开始是检测自己,如果我有活动了,就说明有客户端要连我了. #用select去模拟socket,实现单线 ...

  9. 进程间通讯-2(pipe)

    通过pipe 管道的方式也可以实现进程间通信. 父进程和子进程之间可以实现相互通信. from multiprocessing import Process, Pipe def f(conn): co ...

  10. 简单谈谈Docker镜像的使用方法_docker

    在上篇文章(在Docker中搭建Nginx服务器)中,我们已经介绍了如何快速地搭建一个实用的Nginx服务器.这次我们将围绕Docker镜像(Docker Image),介绍其使用方法.包括三部分: ...