【问题标题】:How does the android build system handle java libraries which load native shared librariesandroid构建系统如何处理加载本机共享库的java库
【发布时间】:2012-03-28 18:33:19
【问题描述】:

考虑以下情况:我有两个名为 P1 和 P2 的 android 项目,它们都生成一个使用相同进程 ID 的 apk,并将在 android 上的同一进程中运行。 P1 和 P2 都使用 Java 库 JL1。 JL1 在运行时加载共享库1 SL1。

我在运行时看到的是,在加载此 SL1 时,有时会出现 java/lang/UnsatisfiedLinkError。 它还输出:共享库已打开。

是什么导致了这个问题?我假设 java 中的库代码在每个项目/apk 中都被复制,并且在运行时当 apk 合并到一个进程中时,它会忘记副本。因此,每个副本都会自行加载其共享库,从而导致已加载错误。

如果是这样,这不是不受欢迎的行为。因为,现在你永远不能在同一个进程中拥有一个包含共享库的 java 库多次使用。

[edit] 我发现每个 apk 都使用自己的类加载器(在同一个进程中也是如此)。这意味着每个 JL 将按 apk 加载类,因此每个共享对象将被加载多次,从而导致错误。有人知道如何解决这个问题吗?是否可以让 apk 共享一个类加载器?

【问题讨论】:

  • 在我看来,您的 P1 和 P2 是由不同的类加载器加载的。你能确认一下吗?如果确实如此,AFAIK 这是预期的行为,即:“同一个 JNI 本机库不能加载到多个类加载器中。” docs.oracle.com/javase/1.4.2/docs/guide/jni/jni-12.html 一种解决方法是设计您的类,以便其中只有一组需要访问本机方法...
  • 我想我必须找出答案。我不知道android如何处理这个。我认为你是对的。如问题中所述。我使用在同一进程中加载​​的两个不同的 apk。我可以想象android会为每个apk实例化一个类加载器。如果为每个进程创建一个类加载器会更好。必须查看android如何处理这个。
  • 我查过了。每个 apk 都有自己的类加载器。所以这意味着共享对象将被加载两次。有什么办法可以解决这个问题?
  • 我会用我自己的分析器来结束这个问题,并将另一个问题发布到 stackoverflow,其中包含有关类加载器细节的信息。
  • 抱歉耽搁了……如果这回答了你的问题,太好了!我猜:)

标签: java android native


【解决方案1】:

每个 apk 都有自己的类加载器。这意味着两个项目/apk 将拥有来自库的自己的类副本。他们在运行时加载。因此,看起来相同的类实际上是副本。因此,在这样的类中加载本机库将导致为每个加载的类加载它(即使这是在静态字段中完成的)。如果两个 apk 共享同一个进程,这会导致多次加载本机共享对象时出现运行时错误。

【讨论】:

    猜你喜欢
    • 2021-05-23
    • 2012-09-19
    • 1970-01-01
    • 2013-02-04
    • 1970-01-01
    • 1970-01-01
    • 2011-07-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多