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

如何解决此问题?


当前回答

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

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

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开发人员

其他回答

这仅适用于针对蜂巢SDK或更高版本的应用程序。针对早期SDK版本的应用程序可以在其主事件循环线程上进行网络连接。

错误是SDK警告!

由于Android是在单个线程上工作的,因此您不应该在主线程上执行任何网络操作。有多种方法可以避免这种情况。

使用以下方法执行网络操作

Asysnctask:用于不需要太多时间的小型手术。意向服务:用于需要大量时间的网络操作。使用Volley和Modification等自定义库进行处理复杂网络操作

千万不要使用StrictMode.setThreadPolicy(策略),因为它会冻结您的UI,根本不是一个好主意。

你可以使用Kotlin和Anko。

Kotlin是Android的新官方语言。您可以在这里找到更多信息:适用于Android的Kotlin。

Anko是Android中Kotlin支持的库。GitHub页面上有一些文档。

这个解决方案非常有用,只有@AntonioLeiva编写的几行代码:使用Anko在Android中使用Kotlin运行后台任务(KAD 09)。

doAsync {
    var result = runLongTask()
    uiThread {
        toast(result)
    }
}

虽然很简单,但当您在UI线程上运行后台作业时,就会出现NetworkOnMainThread,因此您必须做的一件事就是在后台运行longTask作业。你可以在Android应用程序中使用此方法和Kotlin与Anko来完成此操作。

我们还可以使用RxJava将网络操作移动到后台线程。这也相当简单。

webService.doSomething(someData)
          .subscribeOn(Schedulers.newThread())-- This for background thread
          .observeOn(AndroidSchedulers.mainThread()) -- for callback on UI
          .subscribe(result -> resultText.setText("It worked!"),
              e -> handleError(e));

你可以用RxJava做更多的事情。下面是RxJava的一些链接。请随意挖掘。

Android中的RxJava异步任务

http://blog.stablekernel.com/replace-asynctask-asynctaskloader-rx-observable-rxjava-android-patterns/

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

使用服务或异步任务

另请参阅堆栈溢出问题:

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