在项目中遇到一个问题,在 webveiw 和原生之间进行传值的时候,出现了一些 encode 的小问题。看起来很简单的问题,实际上却存在不小的坑。
首先说一下目前项目的结构,在一个 activity 中,webview 和原生之间有多种交互。
如图所示
在原生调用 webview 方法,这种协议已经非常常用了,直接调用 loadJS(); 但是自定义协议这个过程,使用的拦截跳转的方式,按照预定的协议来解析数据,这里面就有一些情况,比如数据中出现了中文,webview 会 encode 这部分内容,这就要求我们对拦截以后的内容进行 decode。
见下方代码:
- 1 private String decodeUrl(String url) {
- 2
- try {
- 3
- return URLDecoder.decode(url, "utf-8");
- 4
- } catch(UnsupportedEncodingException e) {
- 5 e.printStackTrace();
- 6
- }
- 7
- return "";
- 8
- }
上面这段代码,看上去是很合理的,但是老司机们认真看看,这里面有坑。
首先看一下底层代码的 decode。
- /**
- * @throws UnsupportedEncodingException if {@code charsetName} is not supported.
- */
- public static String decode(String s, String charsetName) throws UnsupportedEncodingException {
- return UriCodec.decode(s, true, Charset.forName(charsetName), true);
- }
我想老司机们应该已经明白了是为啥了,就是检查异常和运行时异常的问题了。UnsupportedEncodingException 仅仅是检查时异常,而可能还有运行时异常,因此这里代码需要改为:
- 1 private String decodeUrl(String url) {
- 2 String decodeUrl = "";
- 3
- try {
- 4 decodeUrl = URLDecoder.decode(url, "utf-8");
- 5
- } catch(Exception e) {
- 6 e.printStackTrace();
- 7
- } finally {
- 8
- return decodeUrl;
- 9
- }
- 10
- }
这里对异常进行简单的介绍。
在 Java 中,所有的异常都继承了 Throwable(可抛出)。Throwable 指定代码中可用异常传播机制通过 Java 应用程序传输的任何问题的共性。
Throwable: 有两个重要的子类:Exception(异常)和 Error(错误),二者都是 Java 异常处理的重要子类,各自都包含大量子类。
Error(错误): 是程序无法处理的错误,表示运行应用程序中较严重问题。大多数错误与代码编写者执行的操作无关,而表示代码运行时 JVM(Java 虚拟机)出现的问题。例如,Java 虚拟机运行错误(Virtual MachineError),当 JVM 不再有继续执行操作所需的内存资源时,将出现 OutOfMemoryError。这些异常发生时,Java 虚拟机(JVM)一般会选择线程终止。
。这些错误表示故障发生于虚拟机自身、或者发生在虚拟机试图执行应用时,如 Java 虚拟机运行错误(Virtual MachineError)、类定义错误(NoClassDefFoundError)等。这些错误是不可查的,因为它们在应用程序的控制和处理能力之 外,而且绝大多数是程序运行时不允许出现的状况。对于设计合理的应用程序来说,即使确实发生了错误,本质上也不应该试图去处理它所引起的异常状况。在 Java 中,错误通过 Error 的子类描述。
Exception(异常): 是程序本身可以处理的异常。见图:
运行时异常很常见比如 空指针、非法参数、数组越界、类转换异常、算术异常等。这些异常需要老司机们有经验有技巧的对待,写代码时动用金手指,把这些异常都捕获住。
常见的比如:
- 1 String numberStr = "1";
- 2
- try {
- 3 int number = Integer.valueOf(numberStr);
- 4
- } catch(exception e) {
- 5 e.printStackTrace();
- 6
- }
上面代码没有检查时异常,但是需要老司机捕获住。
当然实际上这里面坑还不止这些,中文符号被 decode 还办好,关键是一些特殊符号不好办。
有些符号在 URL 中是不能直接传递的,如果要在 URL 中传递这些特殊符号,那么就要使用他们的编码了。编码的格式为:% 加字符的 ASCII 码,即一个百分号 %,后面跟对应字符的 ASCII(16 进制)码值。例如 空格的编码值是 " "。
下表中列出了一些 URL 特殊符号及编码。
实际测试中发现,只要替换调 % 就好了。
替换代码为:
- 1 private String decodeUrl(String url) {
- 2 String decodeUrl = "";
- 3
- try {
- 4 String transformUrl = url.replaceAll("%(?![0-9a-fA-F]{2})", "%");
- 5 decodeUrl = URLDecoder.decode(transformUrl, "UTF-8");
- 6
- } catch(Exception e) {
- 7 e.printStackTrace();
- 8
- } finally {
- 9 LogUtil.e("my", "decodeUrl:" + decodeUrl);
- 10
- return decodeUrl;
- 11
- }
- 12
- }
以上代码,通过了表格 8 种符号 全半角形式以及日文韩文的测试,传值和 decode 都是正常的。
来源: http://www.cnblogs.com/xilinch/p/6440008.html