1. 首先本人是新手.如有错误,请多多指教..
2.本文调用的包是 第三方jar包 . ArcSoft 没错,是虹软 (人脸识别相关的)...
尽管在java层有相关代码提供,但是出于某些目的,不方便直接调用...
如果有侵权之处,请谅解,并联系我删除...
开始:
将 jar包,用dx 工具 (位于sdk Sdk/build-tools/xx.x.x ) , 转换成 dex 文件.. 备用..
-----(假如 你已经成功转化,并且你将文件命名为 28.dex,可以把该文件放入到android设备内,切勿push 到 /mnt/sdcard/目录下.. 我这里push到 /data/data/... )
(在class : Jarlocal 内, 有下面代码)
以下是 欲调用的 类名 及方法名:
private static final String className = "com.arcsoft.face.AgeInfo";
private static final String MethodName = "getAge";
以下是 dex1,dex2 的路径:
private static final String jar_path = "/data/data/com.xx.facedemo/28.dex";
private static final String dex_path = "/data/data/com.xx.facedemo/app_dex";
java层 ,详细代码:
这段 code用于 优化生成相关odex?
File dexOutputDir = this.getDir("dex", 0);
DexClassLoader loader = new DexClassLoader("/data/data/com.xxx.facedemo/28.dex", dexOutputDir.getAbsolutePath(),
null, ClassLoader.getSystemClassLoader().getParent());
//dex路径 , odex路径, 类名,方法名
public static native boolean initface(String path1,String path2,String className,String methodname);
public static boolean java_callmethod(){
Log.e(TAG,"java_callmethod---");
return initface(jar_path,dex_path,className,MethodName);
}
jni 层, 详细 代码:
JNIEXPORT bool JNICALL Java_com_xxx_facedemo_Jarlocal_initface(JNIEnv* env,jobject obj,jstring path1,jstring path2,
jstring className,jstring methodName){
//将jstring类型的方法名转换为utf8编码的字符串
const char* func = env->GetStringUTFChars(methodName, NULL);
//找到ClassLoader
jclass classloaderClass = env->FindClass("java/lang/ClassLoader");
jmethodID getsysloaderMethod = env->GetStaticMethodID(classloaderClass, "getSystemClassLoader","()Ljava/lang/ClassLoader;");
jobject loader = env->CallStaticObjectMethod(classloaderClass,getsysloaderMethod);
//jobject loader
jstring dexpath = path1;
jstring dex_odex_path = path2;
jclass dexLoaderClass = env->FindClass("dalvik/system/DexClassLoader");
//DexClassLoader class 4个参数
jmethodID initDexLoaderMethod = env->GetMethodID(dexLoaderClass, "<init>","(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/ClassLoader;)V");
//
jobject dexLoader = env->NewObject(dexLoaderClass,initDexLoaderMethod, dexpath, dex_odex_path, NULL, loader);
//
jmethodID findclassMethod = env->GetMethodID(dexLoaderClass,"loadClass", "(Ljava/lang/String;)Ljava/lang/Class;");
//
//存储需要调用的类
jstring javaClassName = className;
//调用DexClassLoader的loadClass方法,加载需要调用的类
jclass javaClientClass = (jclass)env->CallObjectMethod(dexLoader,findclassMethod,javaClassName);
if(javaClientClass == NULL){
//
}
else{
//获取加载的类中的 方法
jmethodID inject_method = env->GetMethodID(javaClientClass, func, "()I");
if(initDexLoaderMethod == NULL){
return false;
}else{
//调用加载的类中的方法
env->CallVoidMethod(obj,inject_method);
return true;
}
}
return false;
}
以上代码 在android 5.1上测试有效...