2013-06-20 70 views
2

我目前正在開發一個分佈式系統,其節點能夠從服務器下載jar和dex文件以在運行時更改其行爲。不,Android的節點添加使用下面的代碼來調用類加載器提供addURL方法罐子:在運行時將dex添加到Android類路徑

File f = new File(fileName); 
URL u = f.toURI().toURL(); 

URLClassLoader sysloader = (URLClassLoader) ClassLoader.getSystemClassLoader(); 

Class<?> sysclass = URLClassLoader.class; 

try { 
    Method method = sysclass.getDeclaredMethod("addURL", parameters); 
    method.setAccessible(true); 
    method.invoke(sysloader, new Object[] { u }); 
} catch (Throwable t) { } 

是否有可能做一個DEX文件相同的安卓節點上? DexClassLoader和PathClassLoader不提供諸如addURL之類的方法。我知道我可以使用反射來添加單個類,但我不知道如何添加整個dex文件。問題是,如果我將dex中的所有類逐個添加,我會得到缺少依賴關係的異常。這是因爲一個類可能依賴於另一個仍然需要添加的類。無論如何,我用來添加單個類的代碼如下。

File f = new File(pathToSaveFile + dexFile); 
Object obj = null; 
final File optimizedDexOutputPath = context.getDir("outdex", 0); 

DexClassLoader classLoader = new DexClassLoader(
    f.getAbsolutePath(), 
    optimizedDexOutputPath.getAbsolutePath(), null, 
    context.getClassLoader()); 

String path = pathToSaveFile + dexFile; 

try { 
    DexFile dx = DexFile.loadDex(
     path, 
     File.createTempFile("opt", "dex", context.getCacheDir()).getPath(), 
     0); 
    Class<?> myClass = classLoader.loadClass(className); 
} catch (Exception e) { } 

我知道執行動態代碼卸載時的安全問題,但這只是一個研究項目。

回答

1

嘗試代碼https://gist.github.com/nickcaballero/7045993

這種方法種追加新創建DexClassLoader現有之一。

注意它使用反射,因此它可能無法適用於所有Android版本。至少它適用於我的SDK19。

+0

它的工作原理。謝謝 – aleGrazioli

+0

很有幫助。退出一段時間後,谷歌現在對multi-dex有一定的官方支持(主要是繞過着名的65k方法限制)。詳情請參閱https://github.com/casidiablo/multidex。這段代碼可能會涵蓋更多的API版本。 – weidongxu

相關問題