有没有办法使用DexClassLoader而不使用反射*到处*?

时间:2012-07-03 21:59:06

标签: android classloader

我有一个我打算以dex形式使用的库。我想直接针对这个库进行编译,但不能导出它。相反,我想将它放在我的资源中并使用类加载器来实际实例化它。

所以这是我的图书馆:

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: com.library.Foo@413b1b68
E/AndroidRuntime: java.lang.NoClassDefFoundError: com.library.Foo
  ...

有没有办法让FooAccessor使用我传入的类加载器?或者是使用类加载器来反映地狱。

1 个答案:

答案 0 :(得分:1)

你可能想看看这个要点。

https://gist.github.com/nickcaballero/7045993

它使用反射将新的DexClassLoader合并到库存中的BaseDexClassLoader。