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

(从他的例子中。)

其他回答

实际上,您可以启动一个新线程。我以前有过这个问题,并用这种方法解决了它。

永远不要在UI线程上执行任何长时间运行的工作。长时间运行的工作可以是与服务器通信、读取/写入文件等。这些任务应该在后台线程上。这就是创建服务、异步任务和线程的原因。您可以禁用StrictMode,这将防止崩溃。但是,这是绝对不建议的。

我建议您至少在调试模式下利用StrictMode。使用下面的代码获取主线程上减慢应用程序速度的任何问题的日志。

StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
            .detectAll()
            .penaltyLog()
            .build());

您可以设置不同的惩罚:

penaltyLog() // to print log
penaltyDeath() // This will crash you App(so costly penalty)
penaltyDialog() // Show alert when something went lazy on Main thread

这里有更多关于StrictMode的信息:StrictMode|Android开发者。

只是为了明确地说明一些事情:

主线程基本上是UI线程。

因此,如果说您不能在主线程中执行网络操作,则意味着您不能在UI线程中进行网络操作,这意味着您也不能在其他线程中的*runOnUiThread(new Runnable(){…}*块中执行网络操作。

(我只是花了很长时间才弄明白为什么我在主线程之外的其他地方出现了这个错误。这就是为什么;这个线程有帮助;希望这个评论能帮助其他人。)

该错误是由于在主线程中执行长时间运行的操作造成的。您可以使用AsynTask或thread轻松纠正该问题。您可以签出此库AsyncHTTPClient以获得更好的处理。

AsyncHttpClient client = new AsyncHttpClient();
client.get("http://www.google.com", new AsyncHttpResponseHandler() {

    @Override
    public void onStart() {
        // Called before a request is started
    }

    @Override
    public void onSuccess(int statusCode, Header[] headers, byte[] response) {
        // Called when response HTTP status is "200 OK"
    }

    @Override
    public void onFailure(int statusCode, Header[] headers, byte[] errorResponse, Throwable e) {
        // Called when response HTTP status is "4XX" (for example, 401, 403, 404)
    }

    @Override
    public void onRetry(int retryNo) {
        // Called when request is retried
    }
});

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

但如果您愿意接受后果,则可以取消此限制,并覆盖默认行为。

Add:

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

StrictMode.setThreadPolicy(policy);

在你的课堂上,

and

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

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

后果:

你的应用程序(在互联网连接不稳定的地区)将变得无响应并被锁定,用户感觉到速度缓慢,必须进行强制关闭,你冒着活动管理器关闭你的应用并告诉用户应用程序已停止的风险。

Android提供了一些关于良好编程实践的好建议,以设计响应能力:NetworkOnMainThreadException | Android开发人员