1.新建声明本地方法的kt文件
package sss
public class SoInclude {
external fun soIncludeTest():String
}
2.实现它,并Rebuild Project,在build\intermediates\cmake\debug\obj中得到各个架构下的so库文件
JNIEXPORT jstring JNICALL Java_sss_SoInclude_soIncludeTest(JNIEnv* env, jobject) {
return env->NewStringUTF("SoIncludeString");
}
3.将build\intermediates\cmake\debug\obj下的所以so文件以及目录复制到另一个工程的libs目录下
4.在bulid.gradle的Android{…}中添加,中括号就是so库文件所在的根目录
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}
5.使用so库的工程要建同样的包名,并将上一个声明本地方法的kt文件复制过来。
6.使用时还是要init { System.loadLibrary("native-lib") }
这样就可以了,大概就是so已经包含了实现的方法,但是怎么映射到so库里还是要靠声明同样的包类,必须是全部的都要有。
为了不让别人使用自己的so库,可以使用签名认证。
7.添加log.h打印log,signName是已经获得的签名,使用checkSigntrue再次验证,签名相同则调用本地方法时允许,否则不可调用,这样就一定程度上防止他用使用so库。
signName获取
//获取签名信息
var packageInFo = this.packageManager.getPackageInfo(packageName, PackageManager.GET_SIGNATURES)
var sigature = packageInFo.signatures
var rr = sigature[0].toCharsString()
#include "android/log.h"
#define TAG "native"
#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__))
#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__))
jboolean AppFlag = false;
const char* signName = “xxx”;
在external方法中获取签名信息
JNIEXPORT void JNICALL Java_sss_SoInclude_checkSigntrue(JNIEnv* env, jobject,jobject context) {
jclass ContextClass = env->GetObjectClass(context);
jmethodID packageNameId = env->GetMethodID(ContextClass,"getPackageName", "()Ljava/lang/String;");
jstring packageName = (jstring)env->CallObjectMethod(context,packageNameId); //强制转换类型,获得包名
jmethodID packManagerMID = env->GetMethodID(ContextClass,"getPackageManager","()Landroid/content/pm/PackageManager;");
jobject packageManager = env->CallObjectMethod(context,packManagerMID);
jclass PackMangerClass = env->GetObjectClass(packageManager);
jmethodID getInfoID = env->GetMethodID(PackMangerClass,"getPackageInfo", "(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;");
jobject packageInfo = env->CallObjectMethod(packageManager,getInfoID,packageName,0x00000040);
jclass infoclass = env->GetObjectClass(packageInfo);
jfieldID signturesFid = env->GetFieldID(infoclass,"signatures", "[Landroid/content/pm/Signature;");
jobjectArray result = (jobjectArray) env->GetObjectField(packageInfo,signturesFid);
jobject firstResult = env->GetObjectArrayElement(result,0);
jclass firstClass = env->GetObjectClass(firstResult);
jmethodID firstMid = env->GetMethodID(firstClass,"toCharsString", "()Ljava/lang/String;");
jstring finalResult = (jstring)env->CallObjectMethod(firstResult,firstMid);
const char* sss = env->GetStringUTFChars(finalResult,NULL);
jint gg = strcmp(sss,signName);
// string jstr2Str = jstring2str(env,finalResult);
if(gg==0){
AppFlag = true;
LOGI("签名一样");
} else{
AppFlag = false;
LOGI("签名不一样");
}
}