今天遇到一个错误:华为荣耀无法调用微信支付,这是表面现象,在跑测试的过程中出现了报错。
java.lang.IllegalAccessError: Method 'void org.jdom2.ContentList.sort(java.util.Comparator)' implementing interface method 'void java.util.List.sort(java.util.Comparator)' is not public (declaration of 'org.jdom2.ContentList' appears in /data/data/com.yours/files/instant-run/dex/slice-jdom-2.0.2_014ee80a44c7c143027968a0496d006fe2a71ca2-classes.dex)
首先说明一点的是微信支付回传的带有预支付ID的微信XML在Android端我是用SAX解析的,类似如下代码:
StringReader read = new StringReader(entity);
InputSource source = new InputSource(read);
SAXBuilder sb = new SAXBuilder();
try {
Document doc = sb.build(source);
Element weixin = doc.getRootElement();
} catch (Exception e) {
}
我不知道这样是不是很low,但是的确这样的编码抗了一阵线上生产。
到了这个新项目,一切本来很好,但是一个偶然发现了问题,就是华为荣耀系列测试机。之前三星系列和华为其他系列包括小米的各种系列都是没有问题的。
我生成的是正式的Android签名包,所以从报错信息来看是在Android的dex文件中解析XML的jdom底层方法出现了无法访问的限制(is not public)。
不过项目面临上线,也没有多考虑,直接换成了Dom解析。代码如下:
InputStream in = new ByteArrayInputStream(entity.getBytes());
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
org.w3c.dom.Document document = builder.parse(in);
NodeList weixinList = document.getElementsByTagName("weixin");
然后循环迭代weixinList,分别获取需要的字段信息:
Node weixinNode = weixinList.item(0);
if (weixinNode != null) {
NodeList weixinChilds = weixinNode.getChildNodes();
for (int j = 0; j < weixinChilds.getLength(); j++) {
Node childNode = weixinChilds.item(j);
if ("appid".equals(childNode.getNodeName())) {
appid = childNode.getTextContent();
} else if ("partnerid".equals(childNode.getNodeName())) {
partnerid = childNode.getTextContent();
} else if ("prepayid".equals(childNode.getNodeName())) {
prepayId = childNode.getTextContent();
} else if ("package".equals(childNode.getNodeName())) {
packageValue = childNode.getTextContent();
} else if ("noncestr".equals(childNode.getNodeName())) {
nonceStr = childNode.getTextContent();
} else if ("timestamp".equals(childNode.getNodeName())) {
timeStamp = childNode.getTextContent();
} else if ("sign".equals(childNode.getNodeName())) {
sign = childNode.getTextContent();
}
}
令我汗颜的是没有深入追究这个问题的产生原因,这可能要了解jdom的源码以及其与Android底层调用的关系,我只是用一个解决方案替代之前的方案,掩盖了一个问题,因为时间有限,所以先在此记录,后续要深入追究这个问题。Dom解决方案我在小米、三星和所有的华为系列进行了复测,都没有问题,网友可以放心使用Dom解析方式在Android中拆解XML。
感谢你能看到这里,也抱歉一声没有给出原理层的解决方案。后续加油了。