package com.example.hellojni;
public class SoTool {
static {
System.loadLibrary("hello-jni");
}
/*参数说明:android JNI方式调用Jar包
* path1: jar存储路径
* path2: 经过优化后的dex存存放路径
* className: 需要调用jar包中的类名
* methodName: 需要调用的类中的静态方法
* 注意:path1 和path2将会作为DexClassLoader构造函数中的第一、第二参数
*/
public static native void exeJar(String dexPath, String optPath, String className, String methodName);
public static native String stringFromJNI();
}
static void Java_com_example_hellojni_HelloJni_exeJar(JNIEnv *env, jclass cls,jstring path1, jstring path2, jstring className, jstring methodName) {
//找到ClassLoader类
jclass classloaderClass =(*env)->FindClass(env,"java/lang/ClassLoader");
//找到ClassLoader类中的静态方法getSystemClassLoader
jmethodID getsysloaderMethod =(*env)->GetStaticMethodID(env,classloaderClass, "getSystemClassLoader","()Ljava/lang/ClassLoader;");
//调用ClassLoader中的getSystemClassLoader方法,返回ClassLoader对象
jobject loader =(*env)->CallStaticObjectMethod(env,classloaderClass,getsysloaderMethod);
//jar包存放位置
jstring dexpath = path1;
//优化后的jar包存放位置
jstring dex_odex_path = path2;
//找到DexClassLoader类
jclass dexLoaderClass =(*env)->FindClass(env,"dalvik/system/DexClassLoader");
//获取DexClassLoader的构造函数ID
jmethodID initDexLoaderMethod =(*env)->GetMethodID(env,dexLoaderClass, "<init>","(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/ClassLoader;)V");
//新建一个DexClassLoader对象
jobject dexLoader =(*env)->NewObject(env,dexLoaderClass,initDexLoaderMethod, dexpath, dex_odex_path, NULL, loader);
//找到DexClassLoader中的方法findClass
jmethodID findclassMethod =(*env)->GetMethodID(env,dexLoaderClass,"findClass", "(Ljava/lang/String;)Ljava/lang/Class;");
//如果返回空,那就找DexClassLoader的loadClass方法
//说明:老版本的SDK中DexClassLoader有findClass方法,新版本SDK中是loadClass方法
if(NULL==findclassMethod)
{
//
findclassMethod =(*env)->GetMethodID(env,dexLoaderClass,"loadClass", "(Ljava/lang/String;)Ljava/lang/Class;");
}
//存储需要调用的类
jstring javaClassName = className;
//调用DexClassLoader的loadClass方法,加载需要调用的类
jclass javaClientClass=(jclass)(*env)->CallObjectMethod(env,dexLoader,findclassMethod,javaClassName);
//将jstring类型的方法名转换为utf8编码的字符串
const char* func =(*env)->GetStringUTFChars(env,methodName, NULL);
//获取加载的类中的方法
//
jmethodID inject_method =(*env)->GetStaticMethodID(env,javaClientClass, func, "()V");
//调用加载的类中的静态方法
(*env)->CallStaticVoidMethod(env,javaClientClass,inject_method);
}