2017-06-05 35 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