ndk 开发 好处:
1 提升代码运行效率
2 增加软件安全等级 ,增加破解app成本 比如将app核心算法放到so层
3 保护常用校验信息 验证信息
编译第三方库使用场景:
1 提供sdk给其他人用
2 提供静态库给他人用
3 以上两者结合
比如需要写一个解密的函数 提供给外部使用 但是又不想直接给源码 这样会暴露一下关键的算法特征 可以直接编译成.a的静态库提供出去
以下是解密函数 使用到了 aes 和 base64
std::string decode(std::string value)
{
std::string pp = base64_decode(value);
size_t length = pp.length();
char *szDataIn = new char[length + 1];
memcpy(szDataIn, pp.c_str(), length + 1);
char *szDataOut = new char[length + 1];
memcpy(szDataOut, pp.c_str(), length + 1);
//AES解密
AES aes;
aes.MakeKey("testkey123456789", em, 16, 16);
aes.Decrypt(szDataIn, szDataOut, length, AES::CBC);
//去PKCS7Padding填充
if (0x00 < szDataOut[length - 1] <= 0x16)
{
int tmp = szDataOut[length - 1];
for (int i = length - 1; i >= length - tmp; i--)
{
if (szDataOut[i] != tmp)
{
memset(szDataOut, 0, length);
//cout << "解密出错!!" << endl;
break;
}
else
szDataOut[i] = 0;
}
}
string strDest = (szDataOut);
if (szDataIn != NULL)
delete[] szDataIn;
if (szDataOut != NULL)
delete[] szDataOut;
return strDest;
}
Android.mk 编写
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := sgin
LOCAL_MODULE_FILENAME := libsgin
LOCAL_SRC_FILES := \
AES.cpp \
base64.cpp \
Sgin.cpp \
LOCAL_C_INCLUDES := $(LOCAL_PATH)/.
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/.
include $(BUILD_STATIC_LIBRARY)
编译完毕后直接打包为目录sign
其中Android.mk 编写 这里 PREBUILT_STATIC_LIBRARY 为预编译库
根据官方为以下解释:
您必须将自己使用的每个预编译库声明为一个独立模块。为此,请执行以下步骤:
- 为模块提供名称。此名称不需要与预编译库本身的名称相同。
- 在模块的 Android.mk 文件中,将指向您提供的预编译库的路径分配到
LOCAL_SRC_FILES
。指定LOCAL_PATH
变量的值的相对路径。注意:请务必选择与您的目标 ABI 对应的预编译库版本。要详细了解如何确保库支持 ABI,请参阅为预编译库选择 ABI。
- 根据您使用的是共享库 (
.so
) 还是静态库 (.a
),添加PREBUILT_SHARED_LIBRARY
或PREBUILT_STATIC_LIBRARY
。
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := sgin_static
LOCAL_MODULE_FILENAME := sign
LOCAL_SRC_FILES := libsgin.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)
include $(PREBUILT_STATIC_LIBRARY)
第三方使用:
拷贝sign到 jni 目录下
使用 jni 层
#include "Test.h"
#include <string.h>
#include <stdio.h>
#include "Sign.h"
#include <android/log.h>
#define LOG_TAG "test"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
extern "C" {
JNIEXPORT jstring Java_com_example_test_MainActivity_stringFromJNI(JNIEnv* env,
jclass jclazz )
{
return env->NewStringUTF(decode("fnLEDmM4fVglbHVEqRbhq8+whKdGR/XJ/TPkNvA29VjDgZ3f39BMUDaE9laMD0QU").c_str());
}
}
java层
public class MainActivity extends Activity {
public native String stringFromJNI();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tv = (TextView) findViewById(R.id.testText);
tv.setText( stringFromJNI() );
}
static{
System.loadLibrary("test");
}
}
Android.mk编写
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := test
LOCAL_MODULE_FILENAME := libtest
LOCAL_SRC_FILES := Test.cpp
LOCAL_LDLIBS :=-llog
#LOCAL_C_INCLUDES := \
LOCAL_STATIC_LIBRARIES := sign_static
#LOCAL_STATIC_LIBRARIES := libs/${TARGET_ARCH_ABI}/libsgin.a
LOCAL_C_INCLUDES := $(LOCAL_PATH)
include $(BUILD_SHARED_LIBRARY)
#导入sign库
$(call import-module,sign)