2012-07-03 68 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

回答

相关问题