博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[Android NDK/JNI-1A]-开发环境搭建
阅读量:6705 次
发布时间:2019-06-25

本文共 4392 字,大约阅读时间需要 14 分钟。

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文件中加入如下代码:

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

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

#include 
#include "JNI_Demo.h"const char keyValue[] = { 119,119,119,46,104,111,109,105,108,121,46,99,110};JNIEXPORT jbyteArray JNICALL Java_com_homily_SecurityUtil_getKeyValue (JNIEnv *env, jclass obj){ jbyteArray kvArray = (*env)->NewByteArray(env, sizeof(keyValue)); jbyte *bytes = (*env)->GetByteArrayElements(env,kvArray,0); int i; for (i = 0; i < sizeof(keyValue);i++) { bytes[i] = (jbyte)keyValue[i]; } (*env)->SetByteArrayRegion(env,kvArray, 0, sizeof(keyValue),bytes); (*env)->ReleaseByteArrayElements(env,kvArray,bytes,0); return kvArray;}

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

#include 
#ifndef _Included_com_homily_SecurityUtil#define _Included_com_homily_SecurityUtil#ifdef __cplusplusextern "C" {#endifJNIEXPORT jbyteArray JNICALL Java_com_homily_SecurityUtil_getKeyValue (JNIEnv *, jclass);#ifdef __cplusplus}#endif#endif

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

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     @Override11     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文件,如下:

E:\android_workspace\JNI_Demo>NDK-buildAndroid NDK: WARNING: APP_PLATFORM android-19 is larger than android:minS[armeabi] Compile thumb  : JNI_Demo <= JNI_Demo.c[armeabi] SharedLibrary  : libJNI_Demo.so[armeabi] Install        : libJNI_Demo.so => libs/armeabi/libJNI_Demo.so

so文件如下图:

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

参考资料:

 

转载于:https://www.cnblogs.com/royi123/p/5510801.html

你可能感兴趣的文章
生活中的适配器模式——身高不够鞋来凑
查看>>
Veritas推出系统性集成解决方案 帮助全球企业从容应对GDPR条例
查看>>
Java面试----2018最全Redis面试题整理
查看>>
镁客网M-TECH AI助力中国智造产业论坛即将开启,这些大咖在深圳等你
查看>>
专业调酒机器人Foxtender问世
查看>>
Ubuntu 19.04(Disco Dingo)将采用 Linux 5.0 内核
查看>>
ecshop中$user对象
查看>>
一个简单的Julia教程
查看>>
Jenkins连接TFS出现错误:“jenkins com.microsoft.tfs.core.exceptions.TECoreException”的问题收集...
查看>>
Java中String字符串toString()、String.valueOf()、String强转、+ ""的区别
查看>>
vim --Filter commands
查看>>
C231n-SVM-assignment1-完全代码及注释
查看>>
KMP(Knuth-Morris-Pratt)算法
查看>>
阿里云 java程序 链接redis 报错 : IO Error: Connection reset
查看>>
业界 | 如果技术从业者上岗前也要宣誓,一份给程序员的希波克拉底誓言
查看>>
Go语言学习笔记(一)Let&#39;s 干吧
查看>>
MySQL备份脚本
查看>>
Android开发之旅:环境搭建及HelloWorld
查看>>
《我所理解的生活》—读书总结
查看>>
C1000k 新思路:用户态 TCP/IP 协议栈
查看>>