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");
}
これは明らかに醜いです。特に例外処理を含めていないため、そこにはキャッチするスロー可能なオブジェクトが 6 つあるためです。たくさんのものをキャッシュすることができ、速度が少し向上しましたが、それほど多くはありませんでした。
通常、インターフェイスを持つ 3 番目のライブラリを両方とも認識していますが、ライブラリにはいくつかの静的メソッドがあり、とにかく編集できません。次のようなことができれば本当にいいです:
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 に使用させる方法はありますか? それとも、クラスローダーの使用はリフレクション地獄への地獄ですか。