前言:
由于项目中地址接口被反编译而遭受攻击,所以需要对接口地址进行保护,那么这自然要用到Android的NDK开发。其实我在开发的过程中也是在网上找各种资料,然后实现了的。现在我根据我自己的的亲身实践,将自己开发的流程记录下来,方便有需要的人查阅,更多的是为了自己能够学习。
ndk开发主要就是讲敏感的资源放到C文件中,然后通过编译,将C文件打包成动态库.so文件,然后将.so文件加载到libs下面。然后Android项目中就可以获取到C文件中的接口地址了。
ndk开发流程:
1.准备工作
NDK下载地址:
官网地址:https://developer.android.com/ndk/downloads/index.html
- Windows32:http://dl.google.com/android/ndk/android-ndk-r10d-windows-x86.exe
- Windows64:http://dl.google.com/android/ndk/android-ndk-r10d-windows-x86_64.exe
- Mac OS X 32-bit:android-ndk-r10d-darwin-x86.bin
- Mac OS X 64-bit:android-ndk-r10d-darwin-x86_64.bin
- Linux 32-bit (x86):http://dl.google.com/android/ndk/android-ndk-r10d-linux-x86.bin
- Linux 64-bit (x86):http://dl.google.com/android/ndk/android-ndk-r10d-linux-x86_64.bin
- 下载完成之后就是NDK环境的配置了,下面的操作都是在Mac OS X 64-bit平台上完成的。
- 环境配置:
- a.将下载的包安装好
- b.打开终端,执行命令: touch ~/.bash_profile(第一次编辑的时候需要)
- 执行命令: vim ~/.bash_profile
回车进入如下界面,滚动到最下面:
最后一行输入:e
在进入的界面的最后添加
NDK_ROOT就是ndk的安装路径
输入编辑内容后,在输入模式下按esc键,输入 保存并退出命令:
:wq
# 然后执行如下代码,更新配置文件
source .bash_profile
环境配好之后就可以开始操作了
下载ndk文件解压出来会看到里面有个sample文件,里面就是一些范例,如下图:
在Android studio中打开上面截图中的最后一个示例,hello-jni。
对于hello-jni示例会看到有两个jni文件,一个是在main文件夹下面的,一个是在整个工程目录下面的。这两个jni的内容是一模一样的。只是在android中的编译方式不同,在main下面的jni文件,可以在AS中配置相关信息之后,修改jni中的内容之后,自动编译。在外部的jni文件,修改之后内容以后,手动编译。
jni文件夹下有三个文件,如下图:
hello-jin.c文件里面的一个个函数就是与java层桥接的接口。这些函数命名是有约束的,规则如下:
Java_PackageName_ClassName_MethodName
例如:
那么这个函数就对应java中com.example.hellojni包下面的HelloJni类中的getContentFromJNI()函数。
Android.mk文件用来指定源码编译的配置信息,例如工作目录,编译模块的名称,参与编译的文件等,大致内容如下:
- LOCAL_PATH:设置工作目录,而my-dir则会返回Android.mk文件所在的目录。
- CLEAR——VARS:清除几乎所有以LOCAL——PATH开头的变量(不包括LOCAL_PATH)。
- LOCAL_MODULE:用来设置模块的名称。
- LOCAL_SRC_FILES:用来指定参与模块编译的C/C++源文件名。
- BUILD_SHARED_LIBRARY:作用是指定生成的静态库或者共享库在运行时依赖的共享库模块列表。
Application.mk文件用来配置编译平台相关内容,我们最常用的估计只是APP_ABI
字段,它用来指定我们需要基于哪些CPU架构的.so文件
这代表编译所有平台的.so文件。
如果不创建Application.mk文件,那么手动编译的.so文件只有armeabi平台一个版本,其他平台的不会被编译。
当jni文件编写好之后,打开终端,进入到jni所在的目录,然后输入命令:ndk-build,那么在jni所在的目录下回多出libs和obj两个目录,打开libs目录,可以看到对应不同平台的.so文件
将这些libhello-jni.so文件拷贝到工程目录的libs文件夹对应的文件夹下
然后在与hello-jni.so文件中对应的类里面添加如下静态代码块:
加载对应的JNI库,hello-jni是JNI库的名字。实际加载动态库的时候,根据不同的拓展成平台真实的动态库文件名,例如在Linux系统上会拓展成libhello_jni.so而在Windows平台上则会拓展成libhello_jni.dll
并用native关键字修饰hello-jni中对应的类,eg:
表示getContentFromJNI()函数由native层实现
这时候就可以在java中调用getContentFromJNI获取到C++层的数据了。到此,ndk 简单开发完成。
下面为demo示例: