2017-06-05 82 views
0

我想从.jar文件加载外部类。它工作正常。Android DexClassLoader如何使用带参数和参数的类

负载类DexClassLoader:

DexClassLoader classLoader = new DexClassLoader(
       libFile.getAbsolutePath(), 
       tmpDir.getAbsolutePath(), 
       null, 
       ClassLoader.getSystemClassLoader()); 
     Class<?> customFileClass = null; // extends File class 
     try { 
      customFileClass = (Class<?>) classLoader.loadClass("test.MyClass"); 
     } catch (ClassNotFoundException e) { 
      // TODO Auto-generated catch block 

     } 

我知道,我怎么可以使用类的内部定义的函数,但我怎么可以这样使用它:

File f = new File("/dir/File.txt"); 

回答

0

搜索后的小时测试,我找到了解决方案。

  1. 定义新DexClassLoader:

    // .jar file must be Dexted. I know 2 ways to do that: 
    // 1. Through console: dx --dex --output="output.jar" "input.jar" 
    // 2. You can import dx.jar from Android-Sdk/build-tools/xx.x.x/lib/dx.jar in your app and convert .jar file with command: 
    // String[] command = new String[] {"--dex", "--output="output.jar", "input.jar"}; 
    // com.android.dx.command.Main.main(command); 
    DexClassLoader classLoader = new DexClassLoader(
    "absolutePathToJarFile", 
    "absolutePathToTmpDir", 
    null, 
    DexClassLoader.getSystemClassLoader()); 
    
  2. 定义类被装载:

    Class<?> myClass = null; 
    myClass = classLoader.loadClass("my.test.app.neededClass"); 
    
  3. 如果类需要的参数,如new myClass("arg1", "arg2");,我们需要创建新的参数类:

    Class<?>[] args = new Class[1]; // 1 is the number of Arguments 
    args[0] = String.class; // First Argument of Type "String" 
    
  4. 将参数与类关联,我们定义了新的构造:

    Constructor<?> constructor = null; 
    try { 
        constructor = myClass.getDeclaredConstructor(args); 
    } catch (NoSuchMethodException e) { 
        // TODO Auto-generated catch block 
    } 
    Object neededClass = null; 
    neededClass = constructor.newInstance("First String Argument");` 
    
  5. 现在,我们可以提取到方法neededClass的内部定义的已知功能,如:

    Method exists = null; 
    exists = myClass.getMethod("exists"); // exists() is the defined boolean Function inside of neededClass. 
    exists.setAccessible(true);   
    if((boolean) exists.invoke(neededClass)){ 
        // do if true 
    } else { 
        // do if false 
    } 
    

的问题类如File是,我们需要调用AsyncTask里面的Method。如果我们尝试调用AsyncTask之外的方法,则将不会调用定义的类函数File.exists(),并且我们会收到错误InvocationTargetException