【问题标题】:UnsatisfiedLinkError (com.esri.core.runtime.LicenseImpl.nativeIsClientIdValid)UnsatisfiedLinkError (com.esri.core.runtime.LicenseImpl.nativeIsClientIdValid)
【发布时间】:2015-04-24 08:26:21
【问题描述】:

在设备中运行应用程序发生错误:

    java.lang.UnsatisfiedLinkError: Native method not found: com.esri.core.runtime.LicenseImpl.nativeIsClientIdValid:(Ljava/lang/String;)Z
        at com.esri.core.runtime.LicenseImpl.nativeIsClientIdValid(Native Method)
        at com.esri.core.runtime.LicenseImpl.a(Unknown Source)
        at com.esri.android.a.b.b(Unknown Source)

相关代码:

import com.esri.android.runtime.ArcGISRuntime;

public class MainActivity extends FragmentActivity implements NavigationDrawerFragment.NavigationDrawerCallbacks {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ArcGISRuntime.setClientId("xxxxxxxxxxxxxxxx");

......

build.gradle:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 19
    buildToolsVersion "21.1.2"

    defaultConfig {
        applicationId "xxx.xxxx.xxxxx"
        minSdkVersion 17
        targetSdkVersion 19
        versionCode 1
        versionName "1.0"
        renderscriptTargetApi 19
        renderscriptSupportModeEnabled true
    }

    packagingOptions {
        exclude 'META-INF/DEPENDENCIES'
        exclude 'META-INF/LGPL2.1'
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/NOTICE'
    }

    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
            applicationVariants.all { variant ->
                variant.outputs.each { output ->
                    output.outputFile = new File(output.outputFile.parent, "xxxx-release.apk")
                }
            }
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:support-v4:21.0.3'
    compile 'com.google.android.gms:play-services:6.5.87'
}

proguard-rules.txt:

-keep class android.view.** { *; }
-keep class com.esri.** { *; }
-keep class javax.servlet.** { *; }
-keep class jcifs.http.** { *; }
-keep class org.apache.http.** { *; }
-keep class org.joda.time.** { *; }
-keep class org.w3c.dom.bootstrap.** { *; }
-keep class org.xmlpull.v1.** { *; }

-dontwarn javax.servlet.**
-dontwarn jcifs.http.**
-dontwarn org.apache.http.**
-dontwarn org.joda.time.**
-dontwarn org.w3c.dom.bootstrap.**
-dontwarn org.xmlpull.v1.**

Logcat:

03-04 18:06:19.213  13255-13255/xxx.xxxx.xxxxx D/dalvikvm﹕ GC_FOR_ALLOC freed 360K, 17% free 35228K/42136K, paused 17ms, total 17ms
03-04 18:06:19.283  13255-13255/xxx.xxxx.xxxxx D/dalvikvm﹕ GC_FOR_ALLOC freed 368K, 16% free 35516K/42136K, paused 14ms, total 14ms
03-04 18:06:19.343  13255-13753/xxx.xxxx.xxxxx D/dalvikvm﹕ GC_FOR_ALLOC freed 408K, 15% free 35859K/42136K, paused 14ms, total 14ms
03-04 18:06:19.353  13255-13753/xxx.xxxx.xxxxx W/dalvikvm﹕ Failed processing annotation value
03-04 18:06:19.353  13255-13753/xxx.xxxx.xxxxx W/dalvikvm﹕ Exception Ljava/lang/NoSuchFieldError; thrown while initializing Lorg/b/a/d/e/z;
03-04 18:06:19.353  13255-13753/xxx.xxxx.xxxxx W/dalvikvm﹕ Exception Ljava/lang/NoSuchFieldError; thrown while initializing Lorg/b/a/d/an;
03-04 18:06:19.353  13255-13753/xxx.xxxx.xxxxx W/dalvikvm﹕ Exception Ljava/lang/NoSuchFieldError; thrown while initializing Lcom/esri/core/internal/util/d;
03-04 18:06:19.353  13255-13754/xxx.xxxx.xxxxx I/dalvikvm﹕ Rejecting re-init on previously-failed class Lcom/esri/core/internal/util/d; v=0x0
03-04 18:06:19.423  13255-13255/xxx.xxxx.xxxxx D/dalvikvm﹕ GC_FOR_ALLOC freed 776K, 15% free 35950K/42136K, paused 14ms, total 14ms
03-04 18:06:19.443  13255-13756/xxx.xxxx.xxxxx I/dalvikvm﹕ Rejecting re-init on previously-failed class Lcom/esri/core/internal/util/d; v=0x0
03-04 18:06:19.453  13255-13755/xxx.xxxx.xxxxx I/dalvikvm﹕ Rejecting re-init on previously-failed class Lcom/esri/core/internal/util/d; v=0x0

我使用:Android Studio 1.0.2 和 ArcGIS SDK 10.2.5

如果应用由 Android Studio 运行,则没有问题。如果应用在 APK 中生成,安装在设备中,然后运行,则会发生错误。

有什么解决办法吗?

非常感谢!

Similar question答案无效。

【问题讨论】:

  • 请贴出你的代码(包括原生代码)
  • 我在使用 SONIC-NDK 时遇到了同样的错误。当so文件丢失时会发生此错误..
  • 包含相关代码。
  • 看起来你错过了原生库。请检查您是否已包含 ArcGIS SDK 10.2.5 的 .so 文件。
  • 你能告诉我如何检查吗?该应用程序可以由 Android Studio 运行。谢谢。

标签: android arcgis unsatisfiedlinkerror


【解决方案1】:

您的问题与 ProGuard 有关。当您在发布模式下部署应用程序时,ProGuard 会启动并缩小您所有的方法/类/变量/等。这意味着如果一个方法曾经被称为“doSomething()”,它将被重命名为“@ 987654324@"。这很好,因为当您的所有代码都发生这种情况时,它会使您的代码更小更快。

这可能是使用 NDK 的问题,因为原生库与 Java 方法通信的方式是通过反射,这需要命名一致性(通过文本名称找到方法。如果名称更改,则找不到方法)。

您可以通过编辑 ProGuard 文件以排除某些类来解决此问题。

例如,在您的情况下,我会在您的 ProGuard 文件中添加以下行:

-keep class com.esri.core.runtime.LicenseImpl { *; }

其实,你可以让这条规则更加具体,只排除有问题的方法:

-keep class com.esri.core.runtime.LicenseImpl { 
    public void nativeIsClientIdValid(...);
}

ProGuard 在决定代码的哪些部分是否被缩小时非常强大,所以我建议reading up on it.

可能还有其他类需要以类似的方式从 ProGuard 中排除,因此如果您在添加此修复后继续收到类似错误,只需添加更多 ProGuard 规则,具体取决于哪些方法/类没有找到了。

编辑:

根据您收到的新错误,proguard 似乎正在重构注释,这可能是您的新错误的原因。添加以下标志以排除注释:

-keepattributes *Annotation*

编辑 2:

根据this blog about migrating projects to Android studio in the Esri website 的说法,他们似乎还没有找到解决ProGuard 问题的方法,因为他们建议将enableMinify 设置为false。这可能意味着 Esri 软件包此时根本无法使用缩小,或者他们没有投入时间来弄清楚如何解决问题。

【讨论】:

  • 谢谢。 proguard-rules.txt 包含在问题中。该应用程序现在无法查看地图。它只显示一个黑色区域。 Logcat 也包括在内。是否与 NoSuchFieldError 有关?
  • 注释似乎有问题。请查看我的编辑。
  • 添加“-keepattributes Annotation”行后,出现同样的错误。感谢博客链接,我同意 esri 可能不支持 proguard。所以......也许我不得不放弃并将“minifyEnabled”设置为“false”......
  • 或者考虑使用不同的包:/也许他们会很快解决这个问题。
【解决方案2】:

将此添加到您的 proguard 文件中。这不会对您的库应用混淆

-keep class com.esri.** { *; }
-keep interface com.esri.** { *; }

【讨论】:

    【解决方案3】:
    -keep class com.esri.** { *; }
    -keep interface com.esri.** { *; }
    -keep class org.codehaus.jackson.** { *; }
    -dontwarn org.codehaus.jackson.map.ext.**
    -dontwarn jcifs.http.**
    

    为我工作。

    【讨论】:

    • 非常感谢!你救了我的命!从那以后我一直在努力!最后你的解决方案奏效了。
    【解决方案4】:

    我遇到了同样的问题,并按照this link on Esri GeoNet 中的说明解决了。

    根据 EsriStaff 所写的内容:

    是的,我同意这很可能是正在发生的事情。我可以在上面的路径中看到涉及 arm64 路径,并且上面还有一条评论说一切正常,直到添加另一个依赖项。鉴于这两点,您很可能会遇到这样的问题:一旦 Android 加载了 64 位本机库,它就不再加载 32 位库。 [...]ArcGIS 运行时 SDK 提供 32 位 armeabi-v7a 库,通常会在 64 位上运行时加载,因为它向前兼容,这可以解释为什么在添加更多依赖项之前你会发现一切正常。

    正如 EsriGeoNet 中链接的 SO question 所暗示的,解决方案是将其添加到您的 app.gradle 文件中:

    android {
        ....
        defaultConfig {
            ....
            ndk {
                abiFilters "armeabi", "armeabi-v7a", "x86", "mips"
            }
        }
    }
    

    此时运行 gradle 构建应该会给您一个 NDK 已弃用的集成错误,您可以通过在您的 gradle.properties(全局属性)文件中添加它来解决该错误:

    android.useDeprecatedNdk = true
    

    我已经在装有 Android 6.0.1 的三星 S6 上进行了测试,并且工作正常。

    除此之外,我发现 ArcGis Android SDK v10.2.3 中已经存在该问题,升级到最新的 v10.2.8.1 并不能解决该问题。

    下周我们的员工将与 Esri 意大利办事处举行会议,我将询问有关此错误的详细信息以及是否/何时修复。

    希望这对您和遇到此问题的其他人有所帮助。

    【讨论】:

      猜你喜欢
      • 2012-05-28
      • 2016-10-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-24
      • 1970-01-01
      相关资源
      最近更新 更多