在运行时从jar文件加载的Class上的FindClass

时间:2013-09-26 11:12:43

标签: java android c++ java-native-interface

在解决这个问题几天后,我正在办理我的办公桌。

我的原生Android应用程序在运行时加载一个类,这有效我跟着this tutorial从assets文件夹中获取dexed jar并加载了类并成功调用了它的静态方法。

但是,如果我跑...

env->FindClass("TheClass"); 

...抛出了一个java异常。

这里是代码的相关位

//this works find and gives me a usable class
jclass shim_class = helper.LoadClassFromAssetsJar("test.jar","TheClass");
// this throws the exception    
jclass refound_shim_class = jni->FindClass("TheClass"); 

任何帮助都会令人难以置信,为人们欢呼

1 个答案:

答案 0 :(得分:1)

这里有各种各样的东西。

首先,正如@Alex Cohn所说,我们需要保留使用'global references'轻松完成的类,这将使作业(或jclass等)不被重新分配,直到它被释放。我正在考虑这个效果是本地线程,因为这是一些早期版本的android(据我所知)

接下来,由于我不会厌倦你的原因,我们正在使用DexClassloader,因为我们正在从资源文件夹(see here for how that works)加载我们的apk,所以我们还需要保持这一点。 FindClass只能在它自己的上下文中工作,该上下文用于加载系统类(though you can load your own if you do this)

现在我们需要能够在每个线程中使用apk中的类,因此当我们使用pthread_key为每个线程创建JniEnv缓存时,我们运行declassloader.loadclass。这样我们就可以在任何地方获得类,并通过keythread回调自动释放。

无论如何这就足够了。祝你好运!

P.S。一个侧面说明,一旦jni方法抛出了一个无法解决的异常,你无法保证任何其他调用都能正常工作......有些人会,有些人不会,有些人会导致段错误...所以从Java方面自由地抓住保护本机方免受java恶意!