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

如何解决此问题?


当前回答

这里有一个使用OkHttp、Future、ExecutorService和Callable的简单解决方案:

final OkHttpClient httpClient = new OkHttpClient();
final ExecutorService executor = newFixedThreadPool(3);

final Request request = new Request.Builder().url("http://example.com").build();

Response response = executor.submit(new Callable<Response>() {
   public Response call() throws IOException {
      return httpClient.newCall(request).execute();
   }
}).get();

其他回答

从主(UI)线程访问网络资源会导致此异常。使用单独的线程或AsyncTask访问网络资源以避免此问题。

在Android上,网络操作不能在主线程上运行。您可以使用线程、异步任务(短期运行任务)和服务(长期运行任务)来执行网络操作。

不使用strictMode(仅在调试模式下)不更改SDK版本不要使用单独的线程

使用服务或异步任务

另请参阅堆栈溢出问题:

android.os.NetworkOnMainThreadException从android发送电子邮件

对我来说是这样的:

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

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

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

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

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

当应用程序尝试在其主线程上执行网络操作时,会引发此异常。如果您的任务耗时超过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
    }
}