2013-08-27 193 views
2

我正在使用DexClassLoader进行一些测试,以查看是否可以用新功能“更新”我的应用程序。目前我已经有了这种测试方法,它可以和testClass一起运行,并运行test()方法..我想知道的是,我怎样才能“替换”或“更新”和已经存在的类。欢迎任何想法或其他建议。DexClassLoader - 添加功能

方法:

public static void loadExtLib(String pathDexFile, Context ctx) { 

    String temp = ctx.getDir("temp", 0).toString(); 


     DexClassLoader classLoader = new DexClassLoader(pathDexFile, 
        temp, null, ctx.getClass().getClassLoader()); 


      String testClass = "com.mystudio.myapp.TestClass"; 
      Class<?> libProviderClass = null; 
      try { 
      libProviderClass = classLoader.loadClass(testClass); 
     } catch (ClassNotFoundException e1) { 

      e1.printStackTrace(); 
     } 


      try { 
      Method m = libProviderClass.getDeclaredMethod("test", null); 
      try { 
       m.invoke(libProviderClass, null); 

      } catch (IllegalArgumentException e) { 
       e.printStackTrace(); 
      } catch (IllegalAccessException e) { 
       e.printStackTrace(); 
      } catch (InvocationTargetException e) { 
       e.printStackTrace(); 
      } 
     } catch (NoSuchMethodException e1) { 
      e1.printStackTrace(); 
     } 
      Log.v("loadClass", "loaded: " + testClass); 


} 

回答

4

你不能 “替换” 或 “更新” 一类一般;只有DexClassLoader加载的类或其子加载器才能看到加载的类。例如,您不能用一个版本来代替java.lang.String,这个版本可以绕过类中的安全限制。

这会降低使用相同名称加载多个类的效用。另一方面,它确保类加载器A的操作独立于类加载器B的操作,只要其中一个不是另一个的父代。

使用运行时加载类的一种可能有用的方法是在基类加载器中定义一个由类的“旧”和“新”版本实现的接口。通过接口引用类的实例可以避免“旧”代码无法看到“新”类定义的事实。

(想想这一点的最好办法是精神上标记每类及其类加载器。然后,很明显,你不能传递一个String'newString'old写的功能,但如果他们都实现CharSequence'old那么你可以随时)

Dalvik测试中有一些代码可以执行运行时“替换”,并且可能对通读有帮助。请参阅068-classloader测试。 srcsrc-ex的内容被内置到单独的.jar文件中;后者在运行时加载。

+0

非常有用的信息就在这里,fadden。非常感谢:) 我会尝试通过添加具有更新功能的新类(具有不同名称)的过程,并在新功能可用时替换调用它们的类/方法。 这应该工作,我希望。至少会试试:) – ole