1. 程式人生 > >華為榮耀微信支付報錯

華為榮耀微信支付報錯

今天遇到一個錯誤:華為榮耀無法呼叫微信支付,這是表面現象,在跑測試的過程中出現了報錯。

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。

感謝你能看到這裡,也抱歉一聲沒有給出原理層的解決方案。後續加油了。