java – 如何修复android.os.NetworkOnMainThreadException?

我在为RssReader运行我的Android项目时遇到错误。

码:

URL url = new URL(urlToRssFeed);
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser();
XMLReader xmlreader = parser.getXMLReader();
RssHandler theRSSHandler = new RssHandler();
xmlreader.setContentHandler(theRSSHandler);
InputSource is = new InputSource(url.openStream());
xmlreader.parse(is);
return theRSSHandler.getFeed();

它显示以下错误:

android.os.NetworkOnMainThreadException

我该如何解决这个问题?


当应用程序尝试在其主线程上执行网络操作时,将引发此异常。运行您的代码AsyncTask

class RetrieveFeedTask extends AsyncTask<String, Void, RSSFeed> {

    private Exception exception;

    protected RSSFeed doInBackground(String... urls) {
        try {
            URL url = new URL(urls[0]);
            SAXParserFactory factory = SAXParserFactory.newInstance();
            SAXParser parser = factory.newSAXParser();
            XMLReader xmlreader = parser.getXMLReader();
            RssHandler theRSSHandler = new RssHandler();
            xmlreader.setContentHandler(theRSSHandler);
            InputSource is = new InputSource(url.openStream());
            xmlreader.parse(is);

            return theRSSHandler.getFeed();
        } catch (Exception e) {
            this.exception = e;

            return null;
        } finally {
            is.close();
        }
    }

    protected void onPostExecute(RSSFeed feed) {
        // TODO: check this.exception
        // TODO: do something with the feed
    }
}

如何执行任务:

MainActivity.java文件中,您可以在oncreate()方法中添加此行

new RetrieveFeedTask().execute(urlToRssFeed);

不要忘记将其添加到AndroidManifest.xml文件中:

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

您应该几乎总是在线程上运行网络操作或作为异步任务。

但是,如果您愿意接受后果,可以删除此限制并覆盖默认行为。

加:

StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();

StrictMode.setThreadPolicy(policy); 

在你的班上,

在android manifest.xml文件中添加此权限:    

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

后果:

您的应用程序将(在互联网连接不稳定的区域)变得无法响应并锁定,用户感知缓慢并且必须执行强制终止,并且您冒着活动管理器杀死您的应用并告诉用户该应用已停止的风险。

Android提供了一些关于良好编程实践的好技巧,以设计响应能力:http//developer.android.com/reference/android/os/NetworkOnMainThreadException.html


我用新的方法解决了这个问题Thread

Thread thread = new Thread(new Runnable() {

    @Override
    public void run() {
        try  {
            //Your code goes here
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
});

thread.start();

你可以不执行网络I / O在UI线程上的蜂窝。从技术上讲,这可能在早期版本的Android,但它是一个非常糟糕的主意,因为它会导致你的应用程序停止响应,并可能导致操作系统杀死你的应用程序被用于非常表现。您需要运行后台进程或使用AsyncTask在后台线程上执行网络事务。

Android开发者网站上有一篇关于无痛线程的文章,这是对此的一个很好的介绍,它将为您提供比这里实际提供的更好的答案深度。

添加评论

友情链接:蝴蝶教程