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

如何解决此问题?


当前回答

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

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

其他回答

您不应该在主线程(UI线程)上执行任何耗时的任务,如任何网络操作、文件I/O或SQLite数据库操作。因此,对于这种操作,您应该创建一个工作线程,但问题是您不能直接从工作线程执行任何与UI相关的操作。为此,您必须使用Handler并传递消息。

为了简化所有这些事情,Android提供了各种方式,如AsyncTask、AsyncTaskLoader、CursorLoader或IntentService。因此,您可以根据您的要求使用任何这些。

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

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

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

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

简单地说,

不在UI线程中执行网络工作

例如,如果您执行HTTP请求,则这是一个网络操作。

解决方案:

您必须创建一个新线程或使用AsyncTask类

Way:

把你所有的作品放进去

新线程的run()方法或AsyncTask类的doInBackground()方法。

But:

当您从网络响应中获得一些内容并希望在视图中显示它(如在TextView中显示响应消息)时,需要返回到UI线程。

如果不执行此操作,将获得ViewRootImpl$CalledFromWrongThreadException。

如何

使用AsyncTask时,从onPostExecute()方法更新视图或者调用runOnUiThread()方法并更新run()方法内的视图。

科特林

如果您使用Kotlin,可以使用协程:

fun doSomeNetworkStuff() {
    GlobalScope.launch(Dispatchers.IO) {
        // ...
    }
}

不能在主线程或UI线程上调用网络。在Android上,如果你想呼叫网络,有两个选项-

调用asynctask,它将运行一个后台线程来处理网络操作。您可以创建自己的可运行线程来处理网络操作。

就我个人而言,我更喜欢异步任务。有关详细信息,请参阅此链接。