`java.lang.UnsatisfiedLinkError` 在我在 Android 4.4.* 中 运行 构建的 jar 中
`java.lang.UnsatisfiedLinkError` inside a jar which I build while running in Android 4.4.*
我有一个使用 maven
构建的 jar。生成 jar 的项目没有本机依赖项。它在所有设备上运行良好,除了少数具有 android 4.4.2
和 4.4.4
的设备。谁能帮我解决这个问题,现在我的选择是禁用以下所有设备的功能 5.0
编辑 1:
进一步调试我发现我的单例 class 的 LazyHolder
实现失败,因为在运行时构造函数无法解析静态 class.
Caused by java.lang.UnsatisfiedLinkError: <muted>
at com.a.b.controller.Controller.getInstance + 31(Controller.java:31)
at com.a.b.controller.Controller.k + 184(Controller.java:184)
at com.a.b.core.parser.f.m + 53(ff.java:53)
at com.a.b.core.parser.f.n + 67(f.java:67)
at a.b.c.d.e$classify$$inlined$use$lambda.invokeSuspend(e.java:90)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith + 32(BaseContinuationImpl.java:32)
at kotlinx.coroutines.DispatchedTask.run + 233(DispatchedTask.java:233)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely + 594(CoroutineScheduler.java:594)
at kotlinx.coroutines.scheduling.CoroutineScheduler.access$getSchedulerName$p + 60(CoroutineScheduler.java:60)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run + 742(CoroutineScheduler.java:742)
编辑 2:
我通过将 android 版本传递到我的 jar 中创建了一个修复程序,然后不使用 LazyHolder
低于 4.4.*
或更低的版本。欢迎提出更好的解决方案。
我已经等了一段时间才得到这个问题的合适答案。不幸的是,这不容易重现,并且可能是一个角落场景,因为大多数 android 开发人员并不关心版本 4 或更低版本。所以我决定把我所有的发现作为这个问题的答案。
在我的场景中,我有 LazyHolder(https://en.wikipedia.org/wiki/Initialization-on-demand_holder_idiom) 实现来初始化我的中心对象。但问题是当 运行 在 Android 4.4.* 设备上时,惰性持有者无法获得静态 class。 class 在运行时不可用。我 运行 该应用程序在 android 4.4.2 设备上处于调试模式,并且能够清楚地查明这一点。
进一步阅读,我发现静态 class 可能正在进入另一个 dex 文件,而我的构造函数在一个完全不同的文件中(这在 4.4 中启用 multiDex 时很常见。* 看起来) .
最后,hack 是在 android 版本低于 5 的情况下正常初始化,如果版本高于 5
则使用 lazy-holder
我有一个使用 maven
构建的 jar。生成 jar 的项目没有本机依赖项。它在所有设备上运行良好,除了少数具有 android 4.4.2
和 4.4.4
的设备。谁能帮我解决这个问题,现在我的选择是禁用以下所有设备的功能 5.0
编辑 1:
进一步调试我发现我的单例 class 的 LazyHolder
实现失败,因为在运行时构造函数无法解析静态 class.
Caused by java.lang.UnsatisfiedLinkError: <muted>
at com.a.b.controller.Controller.getInstance + 31(Controller.java:31)
at com.a.b.controller.Controller.k + 184(Controller.java:184)
at com.a.b.core.parser.f.m + 53(ff.java:53)
at com.a.b.core.parser.f.n + 67(f.java:67)
at a.b.c.d.e$classify$$inlined$use$lambda.invokeSuspend(e.java:90)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith + 32(BaseContinuationImpl.java:32)
at kotlinx.coroutines.DispatchedTask.run + 233(DispatchedTask.java:233)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely + 594(CoroutineScheduler.java:594)
at kotlinx.coroutines.scheduling.CoroutineScheduler.access$getSchedulerName$p + 60(CoroutineScheduler.java:60)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run + 742(CoroutineScheduler.java:742)
编辑 2:
我通过将 android 版本传递到我的 jar 中创建了一个修复程序,然后不使用 LazyHolder
低于 4.4.*
或更低的版本。欢迎提出更好的解决方案。
我已经等了一段时间才得到这个问题的合适答案。不幸的是,这不容易重现,并且可能是一个角落场景,因为大多数 android 开发人员并不关心版本 4 或更低版本。所以我决定把我所有的发现作为这个问题的答案。
在我的场景中,我有 LazyHolder(https://en.wikipedia.org/wiki/Initialization-on-demand_holder_idiom) 实现来初始化我的中心对象。但问题是当 运行 在 Android 4.4.* 设备上时,惰性持有者无法获得静态 class。 class 在运行时不可用。我 运行 该应用程序在 android 4.4.2 设备上处于调试模式,并且能够清楚地查明这一点。
进一步阅读,我发现静态 class 可能正在进入另一个 dex 文件,而我的构造函数在一个完全不同的文件中(这在 4.4 中启用 multiDex 时很常见。* 看起来) .
最后,hack 是在 android 版本低于 5 的情况下正常初始化,如果版本高于 5
则使用 lazy-holder