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

FindClass on a Class that was loaded from a jar file at runtime

本文关键字:FindClass 加载 文件 运行时 jar      更新时间:2023-10-16

在处理这个问题几天后,我目前正在用头撞我的桌子。

我的原生 android 应用程序在运行时加载了一个类,这有效,我已经按照本教程从 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"); 

任何帮助都会令人难以置信,伙计们干杯

嗯,

这里有很多东西。

首先,正如@Alex Cohn所说,我们需要保留使用"全局引用"轻松完成的类,这将使jobject(或jclass等(在发布之前不会被重新分配。我认为这种效果是线程本地的,因为这是某些早期版本的 android 中的内容(据我所知(

接下来,出于我不会在这里让您感到厌烦的原因,我们正在使用 DexClassloader,因为我们正在从资产文件夹加载我们的 apk(请参阅此处了解其工作原理(,因此我们还需要保留这一点。FindClass 只能在它自己的上下文中工作,这是用于加载系统类(尽管如果你这样做,你可以加载自己的

(。

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

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

附言旁注,一旦 jni 方法抛出了一个未处理的异常,你就不能保证任何其他调用都会起作用......有些会,有些不会,有些会导致段错误......因此,请从爪哇方面自由捕捉,并保护本地方面免受爪哇方面的肮脏!