2013-08-27 162 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