Android开发中,我们经常会用到.so文件。原因有很多,比如部分方法不想暴露,如加密规则。比如部分秘钥需要存储,哪怕最简单的一个String我们使用.so调用获取这个String,也比直接明文写在代码中要来的安全。
NDK开发环境搭建

0x01

首先新建一个java文件
QQ截图20180507165536-1024x190.png
代码:

public class myJNT {
    static {
        System.loadLibrary("JniTest");
    }
    public static native String Hello();
}

0x02

使用javah工具生成.h文件
QQ截图20180507170454.png

0x03

将生成好的.h文件改为.c文件,并修改其中内容

生成的.h文件:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_rehtt_test_ndk_myJNT */

#ifndef _Included_com_rehtt_test_ndk_myJNT
#define _Included_com_rehtt_test_ndk_myJNT
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_rehtt_test_ndk_myJNT
 * Method:    Hello
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_rehtt_test_ndk_myJNT_Hello
  (JNIEnv *, jclass);

#ifdef __cplusplus
}
#endif
#endif

修改后的.c文件:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_rehtt_test_ndk_myJNT */

#ifndef _Included_com_rehtt_test_ndk_myJNT
#define _Included_com_rehtt_test_ndk_myJNT
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_rehtt_test_ndk_myJNT
 * Method:    Hello
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_rehtt_test_ndk_myJNT_Hello
  (JNIEnv *env, jclass jobj){
  //返回字符串
  return (*env)->NewStringUTF(env,"emmmmmm");
  }

#ifdef __cplusplus
}
#endif
#endif

0x04

打开moduled的build.gradle文件,在defaultConfig下添加代码:

ndk {
moduleName "JniTest"    //编译出来so的名字
ldLibs "log", "z", "m"
abiFilters "armeabi", "armeabi-v7a", "x86"
}

QQ截图20180507171708-1024x554.png

在gradle.properties里面加上:
android.useDeprecatedNdk=true
可能会报错,根据报错提示信息进行相应修改即可。

0x05

Rebuild Project就可以生成so库,在app\build\intermediates\ndk\debug\lib路径下。
如果出现了...\ndk-bundle\ndk-build.cmd'' finished with non-zero exit value 2报错就将app\build\intermediates\ndk\debug\lib下的Android.mk复制到src\main\jni下,并使用ndk -build手动生成so文件。

0x06

myJNT.Hello()即可调用so中的字符串

END

Last modification:October 24, 2019
如果觉得我的文章对你有用,请随意赞赏