我在运行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上,网络操作不能在主线程上运行。您可以使用线程、异步任务(短期运行任务)和服务(长期运行任务)来执行网络操作。

其他回答

不允许在Android上的UI线程上实现网络操作。您将不得不使用AsyncTask类来执行与网络相关的操作,如发送API请求、从URL下载图像等,并使用AsyncTask的回调方法,您可以在onPostExecute中获得结果,您将处于UI线程中,您可以使用web服务或类似的数据填充UI。

示例:假设您想从URL下载图像:https://www.samplewebsite.com/sampleimage.jpg

使用AsyncTask的解决方案:分别为。

    public class MyDownloader extends AsyncTask<String,Void,Bitmap>
    {
        @Override
        protected void onPreExecute() {
            // Show progress dialog
            super.onPreExecute();
        }

        @Override
        protected void onPostExecute(Bitmap bitmap) {
            //Populate Ui
            super.onPostExecute(bitmap);
        }

        @Override
        protected Bitmap doInBackground(String... params) {
            // Open URL connection read bitmaps and return form here
            return result;
        }

        @Override
        protected void onProgressUpdate(Void... values) {
            // Show progress update
            super.onProgressUpdate(values);
        }


    }
}

注意:不要忘记在Android清单文件中添加Internet权限。它会像一个魅力一样发挥作用。:)

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

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

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

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

简单地说,

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

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

解决方案:

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

Way:

把你所有的作品放进去

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

But:

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

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

如何

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

注意:AsyncTask在API级别30中已弃用。AsyncTask | Android开发人员

当应用程序尝试在其主线程上执行网络操作时,会引发此异常。在AsyncTask中运行代码:

class RetrieveFeedTask extends AsyncTask<String, Void, RSSFeed> {

    private Exception exception;

    protected RSSFeed doInBackground(String... urls) {
        try {
            URL url = new URL(urls[0]);
            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();
        } catch (Exception e) {
            this.exception = e;

            return null;
        } finally {
            is.close();
        }
    }

    protected void onPostExecute(RSSFeed feed) {
        // TODO: check this.exception
        // TODO: do something with the feed
    }
}

如何执行任务:

在MainActivity.java文件中,可以在oncreate()方法中添加此行

new RetrieveFeedTask().execute(urlToRssFeed);

不要忘记将其添加到AndroidManifest.xml文件中:

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

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

使用服务或异步任务

另请参阅堆栈溢出问题:

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