在解决这个问题几天后,我正在办理我的办公桌。
我的原生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");
任何帮助都会令人难以置信,为人们欢呼
答案 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恶意!