ITmob-Ly
发布于 2022-09-28 / 361 阅读
0

Android Exception - IllegalCharsetNameException: java.nio.charset.CharsetICU[UTF-8]

异常信息

Fatal Exception: java.nio.charset.IllegalCharsetNameException: java.nio.charset.CharsetICU[UTF-8]
       at java.nio.charset.Charset.checkCharsetName(Charset.java:201)
       at java.nio.charset.Charset.forName(Charset.java:295)
       at java.net.URLEncoder.encode(URLEncoder.java:57)
       at cn.itmob.demo.MainActivity.displayTerms(MainActivity.java:2)
       at android.view.View.performClick(View.java:4796)
       at android.view.View$PerformClick.run(View.java:19889)
       at android.os.Handler.handleCallback(Handler.java:739)
       at android.os.Handler.dispatchMessage(Handler.java:95)
       at android.os.Looper.loop(Looper.java:135)
       at android.app.ActivityThread.main(ActivityThread.java:5356)
       at java.lang.reflect.Method.invoke(Method.java)
       at java.lang.reflect.Method.invoke(Method.java:372)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:947)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:742)

解决方法

因为在 Android 6(Android Marshmallow)和之前的版本中 JDK 的 Charset.toString() 方法的返回值是 java.nio.charset.CharsetICU[UTF-8] ,它作为编码名称肯定是不对的。应该使用 Charset.name() 方法。

例如在 Java 或 Kotlin 代码中使用编码时使用了 toString() 方法获取编码名称:

URLEncoder.encode(json, StandardCharsets.UTF_8.toString());

应该使用 name() 方法:

URLEncoder.encode(json, StandardCharsets.UTF_8.name())

异常相关的源码

如下是不同 Android 版本中 CharsettoString() 方法 JDK 源码:

Android 6(Android Marshmallow)

https://android.googlesource.com/platform/libcore/+/refs/heads/marshmallow-release/luni/src/main/java/java/nio/charset/Charset.java

/**
 * Gets a string representation of this charset. Usually this contains the
 * canonical name of the charset.
 *
 * @return a string representation of this charset.
 */
@Override
public final String toString() {
    return getClass().getName() + "[" + this.canonicalName + "]";
}

Android 7(Android Nougat)

https://android.googlesource.com/platform/libcore/+/refs/heads/nougat-release/ojluni/src/main/java/java/nio/charset/Charset.java

/**
 * Returns a string describing this charset. </p>
 *
 * @return  A string describing this charset
 */
public final String toString() {
    return name();
}

所有Android 7之后的版本不存在这个问题,但是使用时还是应该用 name() 方法避免出现问题。