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

Posted

技术标签:

【中文标题】在 Android Studio 中使用 AsyncTask 解析在线 XML 文件时出现 NetworkOnMainThreadException【英文标题】:NetworkOnMainThreadException when using AsyncTask to parse an online XML file in Android Studio 【发布时间】:2018-10-29 22:16:09 【问题描述】:

我正在构建一个货币转换器,它使用以下 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();

对此的解决方案非常迷茫,因此我们将不胜感激! 谢谢

【问题讨论】:

请edit 向我们展示您是如何执行AsyncTask 的问题。 使用xmlpath.execute() 【参考方案1】:
XMLPath xmlpath = new XMLPath();
xmlpath.doInBackground();

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

【讨论】:

以上是关于在 Android Studio 中使用 AsyncTask 解析在线 XML 文件时出现 NetworkOnMainThreadException的主要内容,如果未能解决你的问题,请参考以下文章

TypeError:无法提取-Javascript Asyn问题

如何在android studio中更新maven依赖

如何在模块(Android Studio)中使用 com.android.databinding?

怎样在Android Studio中使用Uiautomator

在 android studio 中使用设备调试时,Android Logcat 为空

在Android Studio中使用lambda表达式