我在运行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
如何解决此问题?
29条答案
按热度按时间uoifb46i16#
**注意:API级别30中不推荐使用异步任务。
AsyncTask | Android Developers**
当应用程序尝试在其主线程上执行网络操作时,会引发此异常。在
AsyncTask
中运行代码:如何执行任务:
在
MainActivity.java
文件中,可以在oncreate()
方法中添加该行不要忘记将其添加到
AndroidManifest.xml
文件:isr3a4wc17#
该错误是由于在主线程中执行长时间运行的操作导致的,您可以使用AsynTask或Thread轻松纠正该问题。您可以 checkout 此库AsyncHTTPClient以获得更好的处理。
f45qwnt818#
可以选择使用Android Annotations。它将允许您在后台线程中简单地运行任何方法:
注意,尽管它提供了简单易读的优点,但也有其缺点。
f0ofjuux19#
这在Android 3.0及以上版本中发生。从Android 3.0及以上版本开始,他们限制使用网络操作(访问互联网的功能)在主线程/UI线程中运行(从活动中的创建和恢复方法生成)。
这是为了鼓励使用单独的线程进行网络操作。有关如何正确执行网络活动的更多详细信息,请参阅AsyncTask。
ktecyv1j20#
将代码放入:
或:
bjp0bcyl21#
基于网络的操作无法在主线程上运行。您需要在子线程上运行所有基于网络的任务,或者实现AsyncTask。
这是如何在子线程中运行任务:
pepwfjgg22#
您可以使用以下代码禁用严格模式:
不建议这样做:使用
AsyncTask
接口。Full code for both the methods
fhg3lkii23#
1.不要使用strictMode(仅在调试模式下)
1.不要更改SDK版本
1.不要使用单独的螺纹
使用服务或异步任务
另请参阅堆栈溢出问题:
mfpqipee24#
在另一个线程上执行网络操作。
例如:
并将其添加到文件AndroidManifest.xml:
7fhtutme25#
这个问题有两种解决方案。
1.不要在主UI线程中使用网络调用。为此使用异步任务。
1.在*setContentView(R.layout.activity_main);*之后将以下代码写入MainActivity文件:
如果(android.os.Build.VERSION.SDK_INT>9){StrictMode.ThreadPolicy policy=new-StrictMode.ThreadPolicy.Builder().permitAll().Build();StrictModel.SetThreadPolicys(policy);}
并将下面的import语句导入到Java文件中。
ibrsph3r26#
您不能在Hive上的UI线程上执行网络I/O。从技术上讲,这在早期版本的Android上是可能的,但这是一个非常糟糕的主意,因为它会导致你的应用停止响应,并可能导致操作系统因为你的应用表现不好而杀死你的应用。您需要运行后台进程或使用AsyncTask在后台线程上执行网络事务。
Android开发者网站上有一篇关于Painless Threading的文章,这是一篇很好的介绍,它将为您提供比这里实际提供的更深入的答案。
4uqofj5v27#
公认的答案有一些明显的缺点。除非您“真正”知道自己在做什么,否则不建议使用AsyncTask进行联网。一些不利方面包括:
executeOnExecutor
方法并提供替代执行器)。在ICS上串行运行时工作良好的代码在Gingerbread上并发执行时可能会中断,比如说,如果您无意中有执行依赖项的顺序。如果您想避免短期内存泄漏,在所有平台上都有定义良好的执行特征,并且有构建真正健壮的网络处理的基础,那么您可能需要考虑:
1.使用一个为您做得很好的库-在this question中有一个很好的网络库比较,或者
1.使用e1d1e或
IntentService
代替,可能使用e1d 3d1e通过“活动”的onActivityResult
方法返回结果。意向服务方法
缺点:
AsyncTask
更多的代码和复杂性,尽管没有您想象的那么多IntentService
替换为等效的Service
实现来轻松控制这一点,比如this one。正面:
onActivityResult
方法接收下载结果Activity
中从AsyncTask
进行上传,但如果用户上下文切换出应用程序以进行电话呼叫,系统可能会在上传完成之前*终止应用程序。使用活动Service
终止应用程序的可能性更小。IntentService
(如我上面链接的版本),则可以通过Executor
控制并发级别。实施总结
您可以很容易地实现
IntentService
以在单个后台线程上执行下载。步骤1:创建
IntentService
以执行下载。您可以告诉它通过Intent
附加项下载什么,并将其传递给PendingIntent
以用于将结果返回到Activity
:步骤2:在清单中注册服务:
步骤3:从“活动”调用服务,传递服务将用于返回结果的PendingResult对象:
步骤4:在onActivityResult中处理结果:
可以使用包含完整工作的Android Studio/Gradle项目的GitHub项目here。
8cdiaqws28#
我使用新的
Thread
解决了这个问题。t30tvxxf29#
您几乎应该始终在线程或异步任务上运行网络操作
但是,如果你愿意接受后果的话,有可能取消这个限制,并覆盖默认行为。
添加:
在你们班上,
和
后果:
您的应用程序将(在互联网连接不稳定的区域)变得无响应并锁定,用户会感觉到速度缓慢,必须强制停止,您可能会面临活动管理器杀死您的应用并告诉用户应用程序已停止的风险。
Android提供了一些关于良好编程实践的好提示,以设计响应能力:NetworkOnMainThreadException | Android Developers