NDK简介

NDK能干什么:NDK使得在android中,java可以调用C 函数库。

1.Android平台从诞生起,就已经支持C、C++开发。众所周知,Android的SDK基于Java实现,这意味着基于Android SDK进行开发的第三方应用都必须使用Java语言。但这并不等同于“第三方应用只能使用Java”。

2.在Android SDK首次发布时,Google就宣称其虚拟机Dalvik支持JNI编程方式,也就是第三方应用完全可以通过JNI调用自己的C动态库,即在Android平台上,“Java+C”的编程方式是一直都可以实现的。

3.NDK提供了一系列的工具,帮助开发者快速开发C(或C++)的动态库,并能自动将so和java应用一起打包成apk。这些工具对开发者的帮助是巨大的。

4.NDK集成了交叉编译器,并提供了相应的mk文件隔离CPU、平台、ABI等差异,开发人员只需要简单修改mk文件(指出“哪些文件需要编译”、“编译特性要求”等),就可以创建出so。

5.NDK可以自动地将so和Java应用一起打包,极大地减轻了开发人员的打包工作。

6.NDK提供了一份稳定、功能有限的API头文件声明

7.Google明确声明该API是稳定的,在后续所有版本中都稳定支持当前发布的API。从该版本的NDK中看出,这些API支持的功能非常有限,包含有:C标准库(libc)、标准数学库(libm)、压缩库(libz)、Log库(liblog)。

Today

1.NDK并不能显著提升应用效率。我们都觉得C语言比起java来说效率要高出很多,一方面,随着jdk的不断更新,java的效率也随之提高;另一方面,即便使用C语言编码提高了应用效率,但是在java与C相互调用时平白又增大了开销。

2.今天折腾了大半天,才编译出自己想要的so文件。但是android studio集成开发环境中还没尝试。

3.关于Cygwin下载问题,官方放在的step.exe国内今天根本没发弄下来,下载了一个老版本的exe,但是又不给更新。

http://www.redhat.com/services/custom/cygwin/ 在红帽试过,虽然exe能弄下来,但是Cygwin需要的下载的文件根本没法下载(网速太慢,比蜗牛还慢,况且有好几个G的)

http://mirrors.163.com/  网易开源镜像站

http://www.cygwin.cn/site/info/show.php?IID=1003 Cygwin中文网

4.由于Java中的本地方法名称及包路径都是写死在C语言中的,因此本地相关代码不能混淆

5.项目中的JNI目录时编写c/c++的代码区,执行ndk-build命令后会在libs下生成so文件,在运行项目时,也是调用so文件中的相关资源。

为什么要使用NDK

java是半解释型语言,很容易被反汇编后拿到源代码文件,在开发一些重要协议时,我们为了安全起见,使用C语言来编写这些重要的部分,来增大系统的安全性。还有,在一些接近硬件环境下,相信大家都清楚C与java的优劣。

1.代码的保护。由于apk的java层代码很容易被反编译,而C/C++库反汇难度较大。

2.可以方便地使用现存的开源库。大部分现存的开源库都是用C/C++代码编写的。

3.提高程序的执行效率。将要求高性能的应用逻辑使用C开发,从而提高应用程序的执行效率。

4.便于移植。用C/C++写得库可以方便在其他的嵌入式平台上再次使用。

5.Eclipse中ndk配置

NDK开发所需要的环境

1.Android应用开发所需要的开发集成环境(环境变量自己百度)

2.NDK所需要的开发包(C:\java\android-ndk-r7b)

3.linux环境需要下载cygwin(C:\java\cygwin\bin)

4.配置各自的环境变量(JDK,SDK,NDK,cygwin)

JNI编码

1.新建一个android工程

2.在工程目录下添加名为 jni 的文件夹(必须)如下图:

3.在jni文件夹下新建你的.c和.h文件文件(JNI_Demo.c和JNI_Demo.h)

4.在jni文件夹下新建名字为Android.mk文件(文件名符合命名规则都行)

5.在上述.mk文件中加入如下代码:

  1. LOCAL_PATH := $(call my-dir)//当前路径(如果你了解shell语言,应该可以很轻松的理解)
  2.  
  3. include $(CLEAR_VARS)
  4.  
  5. LOCAL_MODULE := JNI_Demo //要生成的.so库名
  6. LOCAL_SRC_FILES := JNI_Demo.c //jni文件夹下的c文件名
  7.  
  8. include $(BUILD_SHARED_LIBRARY)

6.在JNI_Demo.c文件中加入如下代码:

  1. #include <stdio.h>
  2. #include "JNI_Demo.h"
  3.  
  4. const char keyValue[] = {
  5. 119,119,119,46,104,111,109,105,108,121,46,99,110
  6. };
  7.  
  8. JNIEXPORT jbyteArray JNICALL Java_com_homily_SecurityUtil_getKeyValue
  9. (JNIEnv *env, jclass obj)
  10. {
  11. jbyteArray kvArray = (*env)->NewByteArray(env, sizeof(keyValue));
  12. jbyte *bytes = (*env)->GetByteArrayElements(env,kvArray,0);
  13. int i;
  14. for (i = 0; i < sizeof(keyValue);i++)
  15. {
  16. bytes[i] = (jbyte)keyValue[i];
  17. }
  18.  
  19. (*env)->SetByteArrayRegion(env,kvArray, 0, sizeof(keyValue),bytes);
  20. (*env)->ReleaseByteArrayElements(env,kvArray,bytes,0);
  21. return kvArray;
  22. }

7.在JNI_Demo.h文件中加入如下代码:

  1. #include <jni.h>
  2.  
  3. #ifndef _Included_com_homily_SecurityUtil
  4. #define _Included_com_homily_SecurityUtil
  5. #ifdef __cplusplus
  6. extern "C" {
  7. #endif
  8. JNIEXPORT jbyteArray JNICALL Java_com_homily_SecurityUtil_getKeyValue
  9. (JNIEnv *, jclass);
  10.  
  11. #ifdef __cplusplus
  12. }
  13. #endif
  14. #endif

8.然后就是写C对应的Java代码

  1. Java_com_homily_SecurityUtil_getKeyValue

这个是Java类对应的路径,必须以Java开头,com.homily.SeturityUtil.java类下的getKeyValue方法。JNI桥接代码如下:

  1. package com.homily;
  2.  
  3. public class SecurityUtil {
  4. private static byte[] keyValue;
  5.  
  6. static {
  7. System.loadLibrary("JNI_Demo");
  8. keyValue = getKeyValue();
  9. }
  10.  
  11. public static String getValue() {
  12. return new String(keyValue);
  13. }
  14.  
  15. public static native byte[] getKeyValue();
  16.  
  17. }

9.android调用代码如下

  1. package com.homily;
  2. import android.app.Activity;
  3. import android.os.Bundle;
  4. import android.util.Log;
  5.  
  6. public class MainActivity extends Activity {
  7.  
  8. private static final String TAG = "MainActivity";
  9.  
  10. @Override
  11. protected void onCreate(Bundle savedInstanceState) {
  12. super.onCreate(savedInstanceState);
  13.  
  14. setContentView(R.layout.activity_main);
  15. String enstr = SecurityUtil.getValue();
  16. Log.d(TAG, "web address[" + enstr +"]");
  17. }
  18.  
  19. }

NDK编译结果

1.生成so文件

打开cmd,使用cd等相关命令进入该工程目录下  ,运行下面的命令,完成后点击右键刷新下项目,在libs下面就会生成so文件,如下:

  1. E:\android_workspace\JNI_Demo>NDK-build
  2. Android NDK: WARNING: APP_PLATFORM android-19 is larger than android:minS
  3. [armeabi] Compile thumb : JNI_Demo <= JNI_Demo.c
  4. [armeabi] SharedLibrary : libJNI_Demo.so
  5. [armeabi] Install : libJNI_Demo.so => libs/armeabi/libJNI_Demo.so

so文件如下图:

2.最后运行下项目,输出日志如下:

参考资料:

http://mobile.51cto.com/aprogram-434525.htm

http://www.cnblogs.com/devinzhang/archive/2012/02/29/2373729.html

[Android NDK/JNI-1A]-开发环境搭建的更多相关文章

  1. Android发展演变与开发环境搭建

    本人也算是一名比较会玩的Android手机用户,常常关注Android发展的最新情况,并且每年都会熬夜看谷歌的I/O大会,总会第一时间刷入最新的Android版本.接下来简单谈一下Android版本的 ...

  2. Linux下搭建Android NDK , Linux 驱动开发环境

    Eclispe Luna(4.4):http://www.eclipse.org/downloads/ CDT :http://www.eclipse.org/cdt/downloads.php AD ...

  3. android Jni NDK开发环境搭建及其简单实例的编写

    android  Jni  NDK开发环境搭建及其简单实例的编写 由于工作需要,需要采用开发想要的JNI,由于之前没有接触过安卓的开发,所以更加网上的帖子,学习了下.遇到了些问题,然后总结下学习过程中 ...

  4. android NDK开发环境搭建

    android NDK开发环境搭建 2012-05-14 00:13:58 分类: 嵌入式 基于 Android NDK 的学习之旅-----环境搭建 工欲善其事必先利其器 , 下面介绍下 Eclip ...

  5. 【转】android 最新 NDK r8 在window下开发环境搭建 安装配置与使用 详细图文讲解,完整实际配置过程记录(原创)

    原文网址:http://www.cnblogs.com/zdz8207/archive/2012/11/27/android-ndk-install.html android 最新 NDK r8 在w ...

  6. android 最新 NDK r8 在window下开发环境搭建 安装配置与使用 详细图文讲解,完整实际配置过程记录(原创)

      android 最新 NDK r8 在window下开发环境搭建 安装配置与使用 详细图文讲解,完整实际配置过程记录(原创) 一直想搞NDK开发却一直给其他事情耽搁了,参考了些网上的资料今天终于把 ...

  7. android NDK 开发环境搭建

    基于 Android NDK 的学习之旅-----环境搭建 工欲善其事必先利其器 , 下面介绍下 Eclipse SDK NDK Cygwin CDT 集成开发环境的搭建. 1.Android 开发环 ...

  8. Android NDK r8 Cygwin CDT 在window下开发环境搭建 安装配置与使用 具体图文解说

    版权声明:本博客全部文章均为原创.欢迎交流.欢迎转载:转载请勿篡改内容,而且注明出处,谢谢! https://blog.csdn.net/waldmer/article/details/3272500 ...

  9. Android下NDK开发环境搭建

    Android下NDK开发环境搭建 1.     AndroidNDK安装与配置 1.1  NDK简介 Android NDK是一套允许开发人员使用本地代码(如C/C++)进行Android APP部 ...

  10. Cocos2dx-3.0版本 从开发环境搭建(Win32)到项目移植Android平台过程详解

    作为重量级的跨平台开发的游戏引擎,Cocos2d-x在现今的手游开发领域占有重要地位.那么问题来了,作为Cocos2dx的学习者,它的可移植特性我们就需要掌握,要不然总觉得少一门技能.然而这个时候各种 ...

随机推荐

  1. cloudera安装报错 socket.gaierror: [Errno -2] Name or service not known

    有时候安装cloudera会报socket.gaierror: [Errno -2] Name or service not known,或者服务器可能IP或mac地址冲突会引发次错误.导致机器服务不 ...

  2. poj3159 最短路(差分约束)

    题意:现在需要分糖果,有n个人,现在有些人觉得某个人的糖果数不能比自己多多少个,然后问n最多能在让所有人都满意的情况下比1多多少个. 这道题其实就是差分约束题目,根据题中给出的 a 认为 b 不能比 ...

  3. 嵌入式Linux开发——内容介绍与开发环境的搭建

    嵌入式Linux开发步骤 设计自己的硬件系统 编写Bootloader 裁剪自己的Linux内核 开发移植设备驱动 构建根文件系统 开发应用程序 嵌入式Linux学习要点 熟练使用开发工具和相关指令集 ...

  4. java打包压缩文件

    package com.it.simple.util; import java.io.BufferedOutputStream;import java.io.ByteArrayOutputStream ...

  5. 013. asp.net统计网站访问人数

    Global.asax中的代码: <%@ Application Language="C#" %> <script runat="server" ...

  6. 一个LINUX狂人的语录(个人认为很精辟)

    http://blog.chinaunix.net/uid-57160-id-2734431.html?page=2 我已经半年没有使用 Windows 的方式工作了.Linux 高效的完成了我所有的 ...

  7. linux概念之用户,组及权限

    Linux 是一个多用户.多任务的操作系统:我们应该了解单用户多任务和多用户多任务的概念 单用户多任务一个beinan用户,为了完成工作,执行了几个任务:当然beinan这个用户,其它的人还能以远程登 ...

  8. unity,standalone下自定义分辨率不起作用的解法

    写一个Editor脚本AddMenu.cs:using UnityEditor; using UnityEngine; public class AddMenu : EditorWindow { [M ...

  9. RSA openssl_public_encrypt false

    这个问题困扰了我好久,最后发现,原来这个函数只能最大长度为117个字节.如果加密的串超过这个长度,就会返回false.

  10. document cookie用法

    cookie概述 曾经利用一个不变的框架来存储购物栏数据,而商品显示页面是不断变化的,尽管这样能达到一个模拟 全局变量的功能,但并不严谨.例如在导航框架页面内右击,单击快捷菜单中的[刷新]命令,则所有 ...