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

如何解决此问题?


当前回答

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

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

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

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

其他回答

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

发生NetworkOnMainThread异常是因为您在默认线程(即UI线程)上调用了某些网络操作。根据不允许的Android版本Android 3(蜂巢),您应该在主线程之外调用网络操作。

您可以使用AsyncTask、IntentService或创建自己的线程并在run方法内调用。有关详细信息,请访问连接到网络。

我们还可以使用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/

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

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

你可以使用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来完成此操作。