華為榮耀微信支付報錯
阿新 • • 發佈:2019-01-28
今天遇到一個錯誤:華為榮耀無法呼叫微信支付,這是表面現象,在跑測試的過程中出現了報錯。
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。
感謝你能看到這裡,也抱歉一聲沒有給出原理層的解決方案。後續加油了。