我在运行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

如何解决此问题?


当前回答

spektom的顶级答案非常完美。

如果您正在内联编写AsyncTask,而不是作为类扩展,并且在此基础上,如果需要从AsyncTask中获取响应,可以使用如下的get()方法。

RSSFeed feed = new RetreiveFeedTask().execute(urlToRssFeed).get();

(从他的例子中。)

其他回答

当应用程序尝试在其主线程上执行网络操作时,会引发此异常。如果您的任务耗时超过5秒,则需要强制关闭。

在AsyncTask中运行代码:

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

    protected RSSFeed doInBackground(String... urls) {
       // TODO: Connect
    }

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

Android不允许在主线程上运行长时间运行的操作。

因此,只需使用不同的线程,并在需要时将结果发布到主线程。

new Thread(new Runnable() {
        @Override
        public void run() {
            /*
            // Run operation here
            */
            // After getting the result
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    // Post the result to the main thread
                }
            });
        }
    }).start();

使用Android Annotations是一个选项。它将允许您在后台线程中简单地运行任何方法:

// normal method
private void normal() {
    doSomething(); // do something in background
}

@Background
protected void doSomething() 
    // run your networking code here
}

注意,尽管它提供了简单性和可读性的优点,但也有其缺点。

对我来说是这样的:

<uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="10" />

我测试应用程序的设备是4.1.2,即SDK版本16!

确保目标版本与Android目标库相同。如果你不确定你的目标库是什么,右键单击你的项目->构建路径->Android,它应该是勾选的那个。

此外,正如其他人所提到的,包括访问Internet的正确权限:

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

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

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