【问题标题】:Android: Issue using JSON library in pure java packageAndroid:在纯 java 包中使用 JSON 库的问题
【发布时间】:2019-12-07 23:52:21
【问题描述】:

我们的 Android 应用有一个包,其中仅包含与 Android 分离的纯 Java 代码。我需要在这个包中使用 JSON,并尝试导入 official JSON library。虽然导入成功,并且我可以在代码中使用 JSON,但它拒绝工作。我经常遇到同样的异常:

java.lang.NoSuchMethodError: 没有静态方法 g(Ljava/lang/String;)Ljava/lang/Object;在类 Lorg/json/JSONObject 中;或其超类('org.json.JSONObject' 的声明出现在 /system/framework/core-libart.jar 中)

No virtual method b()Z in class Lorg/json/JSONObject; or its super classes (declaration of 'org.json.JSONObject' appears in /system/framework/core-libart.jar)

我不知道我为什么会得到这个。我已经阅读过,这是由于与 Android 包含的 JSON 库发生冲突,但这仅在纯 Java 库中使用,并且与 Android 的任何代码交互都涉及字符串或 long,而不是 JSON

有人经历过吗?或者对如何在这个纯 java 包中使用 JSON 有什么建议?

我尝试导入一个非常旧版本的 JSON 库,以防它是由于某种冲突而导致我使用较新的方法,但没有骰子。同样的错误。还尝试导入 jar 而不是使用 gradle。

这用于ORMLITE 中数据库的简单getter 和setter。这是一个示例,其中 mExtraFlag 是一个字符串。也导致问题的方法是来自 JSONObject 的 toString 以及方法:valueToString、StringToValue 等...

public JSONObject getExtraFlag() {
 return new JSONObject(mExtraFlag);
}

【问题讨论】:

    标签: java android json android-studio gson


    【解决方案1】:

    我猜你的 混淆 构建会引发异常(因为 g(Ljava/lang/String;)Ljava/lang/Object; 显然被混淆了)。

    正如您正确提到的,android 已经提供了一些像org.json 这样的java 库。如果您的一个组件想要使用特定库的不同(例如较新)版本,这尤其是一个问题,但是 android 会简单地用 android 提供的版本替换您的导入,因此,java.lang.NoSuchMethodError 可能是如果您调用仅在较新版本中可用的方法,则会引发。通常,解决这个问题的方法是给包名加阴影,这样就不会被替换。

    但是,在您的情况下,org.json 的错误版本似乎不是问题。抛出该错误是因为您的org.json 包在您的构建中被混淆了,并且混淆的方法g(...) 当然不能在android 的../core-libart.jar 中找到。

    您可能有多种选择来解决此问题:

    • 如果从.jar 导入中使用解耦的java 包,它显然不会作为传递依赖处理,因此,org.json 将作为与android 使用的库不同的库处理,所以org.json 会被混淆。因此,您可以添加一个 proguard 保持规则,例如:
    -keep class org.json.**
    -keepclassmembers,includedescriptorclasses class org.json.** { *; }
    
    • 您可以尝试通过将 lib 处理为传递依赖项来解决此问题。
    • 您可以尝试在解耦组件中隐藏 org.json,但 imo 这不是必需的,最终只会导致两次导入同一个库。

    恕我直言,可能不需要添加像 gson 这样的另一个库。

    【讨论】:

      【解决方案2】:

      对于遇到相同问题的任何人,这是我的 hack 修复。我决定使用gson

      再次,我必须强调这是针对DECOUPLED JAVA PACKAGE如果您尝试在常规 Android 包中导入 JSON 库,这可能不适合您。实际上,其他答案可能适用于您。

      分级:

      dependencies {
          implementation 'com.google.code.gson:gson:2.8.5'
      }
      

      马文:

      <dependencies>
      <!--  Gson: Java to Json conversion -->
          <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.8.5</version>
            <scope>compile</scope>
          </dependency>
      </dependencies>
      

      从字符串解析到 json 对象的示例

      public JsonObject toJson(String value) {
          return new JsonParser().parse(value).getAsJsonObject();
      }
      
      // (probably dosen't require a method)
      public String fromJson(JsonObject json) {
          return json.toString();
      }
      

      如何创建并插入 JSON 对象:

      JsonObject object = new JsonObject();
      object.addProperty(key, value);
      

      获取长值的示例(mExtraFlag 是一个字符串)

      toJson(mExtraFlag).get(key).getAsLong();
      

      【讨论】:

      • Gson 始终是一个很好的解决方案,您也可以使用 Jackson。我保存这个解决方案以备将来使用:)
      • 我猜什么都行,但我不得不将它用于简单的功能,这很糟糕:(我真的只需要它来处理 jsonobjects。Jackson 也可能是个好主意
      猜你喜欢
      • 2011-10-21
      • 2019-08-25
      • 1970-01-01
      • 2019-08-26
      • 1970-01-01
      • 2022-01-09
      • 2015-05-24
      • 1970-01-01
      • 2016-01-28
      相关资源
      最近更新 更多