使用AsyncTask解析Android Studio中的在线XML文件时出现NetworkOnMainThreadException

时间:2018-05-19 19:36:14

标签: android xml parsing android-asynctask

我正在构建一个货币转换器,它使用以下XML API来获取费率:http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml

但是我在函数中遇到了NetworkOnMainThreadException错误。

这是我的XMLPath函数,它应该扫描API并将所有速率保存到ArrayList中:

    private static final String CURRENCY = "currency";
private static final String RATE = "rate";
private static final String CUBE_NODE = "//Cube/Cube/Cube";

public class XMLPath extends AsyncTask<URL, Void, List<Currency_Rate>> {

    @Override
    protected List<Currency_Rate> doInBackground(URL... urls){

        List<Currency_Rate> currRateList = new ArrayList<>();

        DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = null;

        try {
            builder = builderFactory.newDocumentBuilder();
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        }
        Document document = null;
        String target_url = "http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml";

        try{
            URL xmlurl = new URL(target_url);
            InputStream xml = xmlurl.openStream();
            document = builder.parse(xml);

            XPathFactory xPathfactory = XPathFactory.newInstance();
            XPath xpath = xPathfactory.newXPath();
            String xPathString = CUBE_NODE;

            XPathExpression expression = xpath.compile(xPathString);

            NodeList nodel = (NodeList) expression.evaluate(document, XPathConstants.NODESET);

            for (int i = 0; i < nodel.getLength(); i++){

                Node node = nodel.item(i);
                NamedNodeMap attr = node.getAttributes();

                if(attr.getLength() > 0) {
                    Node currencyAttr = attr.getNamedItem(CURRENCY);

                    if(currencyAttr != null){
                        String currency_text = currencyAttr.getNodeValue();
                        String rate_text = attr.getNamedItem(RATE).getNodeValue();
                        currRateList.add(new Currency_Rate(rate_text));

                        Log.i("Rate", rate_text.toString());
                    }
                }
            }
        } catch (SAXException | XPathExpressionException | IOException e) {
            e.printStackTrace();
        }

        for (Currency_Rate currency_rate : currRateList){

            System.out.println(currency_rate);
        }


        return currRateList;
    }

    @Override
    protected void onPostExecute(List<Currency_Rate> currRateList)
    {
        super.onPostExecute(currRateList);
    }

}

我在以下行收到错误:

document = builder.parse(xml);

我在清单文件中启用了互联网访问:

<uses-permission android:name="android.permission.INTERNET" />

修改

在应用程序的MainActivity的OnCreate()中,我调用了类:

    XMLPath xmlpath = new XMLPath();
    xmlpath.doInBackground();

非常失败的解决方案,所以任何帮助将不胜感激! 感谢

1 个答案:

答案 0 :(得分:1)

XMLPath xmlpath = new XMLPath();
xmlpath.doInBackground();

您不应直接致电doInBackground()。而是调用其中一个execute()方法使asynctask在后台线程上运行。