2012-07-03 71 views
1

我有一個圖書館,我打算在dex形式使用。我想直接對這個庫進行編譯,但不能導出它。相反,我想把它放在我的資源中,並使用類加載器來實際實例化它。有沒有辦法使用DexClassLoader而不使用反射*到處*?

因此,這裏是我的圖書館:

public class Foo { 
    public doFoo(String message) { 
    } 

    public doFoo(int count, String message) { 
    } 
} 

現在我想打電話給doFoo()。很多。比使用反射可能更合理。現在它適用於:

public class FooConsumer { 
    private final DexClassLoader fooLoader; 

    public FooConsumer(DexClassLoader fooLoader) { 
    this.fooLoader = fooLoader; 
    } 

    public void go() { 
    Class<?> fooClass = fooLoader.loadClass("com.library.Foo"); 
    Object fooInstance = fooClass.newInstance(); 
    Method fooMethodDoFoo = fooClass.getMethod("doFoo", String.class); 
    fooMethodDoFoo.invoke(fooInstance, "Hello World"); 
    } 

這顯然很難看。特別是因爲我沒有包含任何異常處理,因爲有六十個可拋投資在那裏。我可以緩存一堆東西,以一定的速度幫助我,但不是很多。

通常我都會意識到有一個接口的第三個庫,但庫有一些靜態方法,我無法編輯它。如果我能做這樣的事情真的很好:

public class FooConsumer { 
    private FooAccessor accessor; 

    public FooConsumer(DexClassLoader fooLoader) { 
    Object fooInstance = fooLoader.loadClass("com.library.Foo").newInstance(); 
    Log.i("TEST", "fooInstance: " + fooInstance); 
    this.accessor = new FooAccessor(fooInstance); 
    } 

    public void go() { 
    accessor.doFoo("Hello World"); 
    } 

    private static class FooAccessor { 
    private Foo fooInstance; 

    public FooAccessor(Object instance) { 
     fooInstance = (Foo)instance; 
    } 

    public void doFoo(String message) { 
     fooInstance.doFoo(message); 
    } 
    } 
} 

看看我在那裏做了什麼?內部類僅僅是Foo對象的一個​​包裝,我已經鏈接到它,但沒有導出它,並且在這個世界中一切都很好。但它不起作用。在logcat我得到

I/TEST: fooInstance: [email protected] 
E/AndroidRuntime: java.lang.NoClassDefFoundError: com.library.Foo 
    ... 

有沒有辦法讓FooAccessor使用我傳入的類加載器?或者是使用類裝載機的詛咒進入反思地獄。

+0

只是爲了避免顯而易見的問題,我這樣做是因爲我希望能夠向後兼容Foo的升級,因爲它們可用,而不必推送我的應用程序的全新版本。 – Hounshell

+0

看看這個[博客文章](http://android-developers.blogspot.co.nz/2011/07/custom-class-loading-in-dalvik.html)。 – yorkw

+0

是的,我看到了一個。它並不包括能夠使用靜態方法,它依賴於圖書館的控制權,我很遺憾不是。 – Hounshell

回答

相關問題