如何修复“android.os.NetworkOnMainThreadException”?

这篇具有很好参考价值的文章主要介绍了如何修复“android.os.NetworkOnMainThreadException”?。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

问:

为 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

我该如何解决这个问题?

答1:

保持自己快人一步,享受全网独家提供的一站式外包任务、远程工作、创意产品订阅服务–huntsbot.com

注意:AsyncTask 在 API 级别 30 中已被弃用。 AsyncTask | Android Developers

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

class RetrieveFeedTask extends AsyncTask {

    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 文件:



所以这个在主线程上运行的网络操作只在 android 中而不是在标准 java 代码中存在问题(用 java 编写的代码但不适用于 android 应用程序)。??

这是一个很好的解决方案,它节省了我的时间!

由于 AsyncTask 已被弃用,最新的解决方案是什么?

答2:

保持自己快人一步,享受全网独家提供的一站式外包任务、远程工作、创意产品订阅服务–huntsbot.com

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

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

添加:

StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();

StrictMode.setThreadPolicy(policy);

在你的课堂上,

在 Android manifest.xml 文件中添加此权限:



结果:

您的应用程序将(在互联网连接不稳定的区域)变得无响应并被锁定,用户认为速度很慢并且必须强制终止,并且您冒着活动管理器杀死您的应用程序并告诉用户应用程序已停止的风险。

Android 提供了一些关于响应性设计的良好编程实践的好技巧:NetworkOnMainThreadException | Android Developers

哇,谢谢你的解释,我现在明白了。我看到了一个应用程序,它已经在它的 java 类中实现了 ThreadPolicy,我有点困惑它在做什么。当网络低时,我看到了你所说的后果。

答3:

huntsbot.com – 程序员副业首选,一站式外包任务、远程工作、创意产品分享订阅平台。

我使用新的 Thread 解决了这个问题。

Thread thread = new Thread(new Runnable() {

    @Override
    public void run() {
        try  {
            //Your code goes here
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
});

thread.start(); 

您将如何将参数传递给此?

如果您需要在请求后访问 UI,则需要在最后返回主线程,如 here 所述。

简单而且有效,非常感谢你:)

答4:

huntsbot.com提供全网独家一站式外包任务、远程工作、创意产品分享与订阅服务!

公认的答案有一些明显的缺点。除非您真的知道自己在做什么,否则不建议使用 AsyncTask 进行联网。一些缺点包括:

作为非静态内部类创建的 AsyncTask 具有对封闭 Activity 对象、其上下文以及由该 Activity 创建的整个 View 层次结构的隐式引用。此引用可防止在 AsyncTask 的后台工作完成之前对 Activity 进行垃圾收集。如果用户的连接速度很慢,和/或下载量很大,这些短期内存泄漏可能会成为一个问题——例如,如果方向改变了几次(并且你没有取消正在执行的任务),或者用户导航离开活动。

AsyncTask 具有不同的执行特性,具体取决于它执行的平台:在 API 级别 4 之前,AsyncTask 在单个后台线程上串行执行;从 API 级别 4 到 API 级别 10,AsyncTasks 在多达 128 个线程的池中执行;从 API 级别 11 开始,AsyncTask 在单个后台线程上串行执行(除非您使用重载的 executeOnExecutor 方法并提供替代执行器)。在 ICS 上串行运行时运行良好的代码在 Gingerbread 上并发执行时可能会中断,例如,如果您有无意的执行顺序依赖项。

如果你想避免短期内存泄漏,在所有平台上都有明确定义的执行特征,并且有一个基础来构建真正强大的网络处理,你可能需要考虑:

使用可以为您完成这项工作的库 - 在这个问题中有一个很好的网络库比较,或者使用服务或 IntentService 代替,可能使用 PendingIntent 通过活动的 onActivityResult 方法返回结果。

IntentService 方法

缺点:

比 AsyncTask 更多的代码和复杂性,虽然没有你想象的那么多

将请求排队并在单个后台线程上运行它们。您可以通过将 IntentService 替换为等效的 Service 实现来轻松控制这一点,也许就像这样。

嗯,我现在真的想不出其他人了

优点:

避免短期内存泄漏问题

如果您的活动在网络操作正在进行时重新启动,它仍然可以通过其 onActivityResult 方法接收下载结果

一个比 AsyncTask 更好的平台来构建和重用强大的网络代码。示例:如果您需要进行重要的上传,您可以从 Activity 中的 AsyncTask 进行,但如果用户上下文切换到应用程序之外接听电话,系统可能会在上传完成之前终止应用程序。杀死具有活动服务的应用程序的可能性较小。

如果您使用自己的 IntentService 并发版本(如我上面链接的那个),您可以通过 Executor 控制并发级别。

实施总结

您可以很容易地实现 IntentService 以在单个后台线程上执行下载。

第 1 步:创建一个 IntentService 以执行下载。您可以通过 Intent extras 告诉它要下载什么,并将 PendingIntent 传递给它以用于将结果返回给 Activity:

import android.app.IntentService;
import android.app.PendingIntent;
import android.content.Intent;
import android.util.Log;

import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;

public class DownloadIntentService extends IntentService {

    private static final String TAG = DownloadIntentService.class.getSimpleName();

    public static final String PENDING_RESULT_EXTRA = "pending_result";
    public static final String URL_EXTRA = "url";
    public static final String RSS_RESULT_EXTRA = "url";

    public static final int RESULT_CODE = 0;
    public static final int INVALID_URL_CODE = 1;
    public static final int ERROR_CODE = 2;

    private IllustrativeRSSParser parser;

    public DownloadIntentService() {
        super(TAG);

        // make one and reuse, in the case where more than one intent is queued
        parser = new IllustrativeRSSParser();
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        PendingIntent reply = intent.getParcelableExtra(PENDING_RESULT_EXTRA);
        InputStream in = null;
        try {
            try {
                URL url = new URL(intent.getStringExtra(URL_EXTRA));
                IllustrativeRSS rss = parser.parse(in = url.openStream());

                Intent result = new Intent();
                result.putExtra(RSS_RESULT_EXTRA, rss);

                reply.send(this, RESULT_CODE, result);
            } catch (MalformedURLException exc) {
                reply.send(INVALID_URL_CODE);
            } catch (Exception exc) {
                // could do better by treating the different sax/xml exceptions individually
                reply.send(ERROR_CODE);
            }
        } catch (PendingIntent.CanceledException exc) {
            Log.i(TAG, "reply cancelled", exc);
        }
    }
}

第 2 步:在清单中注册服务:



第 3 步:从 Activity 调用服务,传递一个 PendingResult 对象,服务将使用该对象返回结果:

PendingIntent pendingResult = createPendingResult(
    RSS_DOWNLOAD_REQUEST_CODE, new Intent(), 0);
Intent intent = new Intent(getApplicationContext(), DownloadIntentService.class);
intent.putExtra(DownloadIntentService.URL_EXTRA, URL);
intent.putExtra(DownloadIntentService.PENDING_RESULT_EXTRA, pendingResult);
startService(intent);

第四步:在onActivityResult中处理结果:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == RSS_DOWNLOAD_REQUEST_CODE) {
        switch (resultCode) {
            case DownloadIntentService.INVALID_URL_CODE:
                handleInvalidURL();
                break;
            case DownloadIntentService.ERROR_CODE:
                handleError(data);
                break;
            case DownloadIntentService.RESULT_CODE:
                handleRSS(data);
                break;
        }
        handleRSS(data);
    }
    super.onActivityResult(requestCode, resultCode, data);
}

提供了一个 GitHub 项目,其中包含一个完整的 Android Studio/Gradle 项目here。

huntsbot.com聚合了超过10+全球外包任务平台的外包需求,寻找外包任务与机会变的简单与高效。

答5:

huntsbot.com汇聚了国内外优秀的初创产品创意,可按收入、分类等筛选,希望这些产品与实践经验能给您带来灵感。

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

Android 开发者网站上有一篇关于 Painless Threading 的文章对此进行了很好的介绍,它将为您提供比此处实际提供的更深入的答案。

答6:

huntsbot.com提供全网独家一站式外包任务、远程工作、创意产品分享与订阅服务!

这个问题有两种解决方案。

不要在主 UI 线程中使用网络调用。为此使用异步任务。在 setContentView(R.layout.activity_main);: if (android.os.Build.VERSION.SDK_INT > 9) { StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll( )。建造(); StrictMode.setThreadPolicy(policy); }

并将下面的 import 语句放入您的 Java 文件中。

import android.os.StrictMode;

遵循您的第二个解决方案是一种不好的做法。异步是正确执行此操作的方法。如果您更改政策,您就像隐藏您的问题!

答7:

huntsbot.com聚合了超过10+全球外包任务平台的外包需求,寻找外包任务与机会变的简单与高效。

在另一个线程上执行网络操作。

例如:

new Thread(new Runnable(){
    @Override
    public void run() {
        // Do network action in this function
    }
}).start();

并将其添加到文件 AndroidManifest.xml:



答8:

huntsbot.com高效搞钱,一站式跟进超10+任务平台外包需求

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

使用 Service 或 AsyncTask

另请参阅堆栈溢出问题:

android.os.NetworkOnMainThreadException sending an email from Android

也许值得强调一点,如果你使用服务,你仍然需要创建一个单独的线程——服务回调在主线程上运行。另一方面,IntentService 在后台线程上运行其 onHandleIntent 方法。

您不应该将 AsyncTask 用于长时间运行的操作!指南指定最多 2 到 3 秒。

答9:

huntsbot.com精选全球7大洲远程工作机会,涵盖各领域,帮助想要远程工作的数字游民们能更精准、更高效的找到对方。

您可以使用以下代码禁用严格模式:

if (android.os.Build.VERSION.SDK_INT > 9) {
    StrictMode.ThreadPolicy policy = 
        new StrictMode.ThreadPolicy.Builder().permitAll().build();
    StrictMode.setThreadPolicy(policy);
}

不建议这样做:使用 AsyncTask 界面。

Full code for both the methods

是的,会出现 ANR 错误。表示应用程序在 5 秒内没有响应。

这是一个非常糟糕的答案。您不应该更改线程的策略,而是编写更好的代码:不要在主线程上进行网络操作!

答10:

huntsbot.com聚合了超过10+全球外包任务平台的外包需求,寻找外包任务与机会变的简单与高效。

基于网络的操作不能在主线程上运行。您需要在子线程上运行所有基于网络的任务或实现 AsyncTask。

这是在子线程中运行任务的方式:

new Thread(new Runnable(){
    @Override
    public void run() {
        try {
            // Your implementation goes here
        } 
        catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}).start();

Anonymous Runnable 不是最好的方法,因为它对封闭类有一个隐式引用,并防止它在线程完成之前被 GC 编辑!此外,该线程将以与主/美国线程相同的优先级运行,与生命周期方法和 UI 帧速率竞争!

答11:

打造属于自己的副业,开启自由职业之旅,从huntsbot.com开始!文章来源地址https://www.toymoban.com/news/detail-762582.html

将您的代码放入:

new Thread(new Runnable(){
    @Override
    public void run() {
        try {
            // Your implementation
        }
        catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}).start();

或者:

class DemoTask extends AsyncTask {

    protected Void doInBackground(Void... arg0) {
        //Your implementation
    }

    protected void onPostExecute(Void result) {
        // TODO: do something with the feed
    }
}

原文链接:https://www.huntsbot.com/qa/YlLZ/how-can-i-fix-android-os-networkonmainthreadexception?lang=zh_CN&from=csdn

打造属于自己的副业,开启自由职业之旅,从huntsbot.com开始!

到了这里,关于如何修复“android.os.NetworkOnMainThreadException”?的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 谷歌开源Fuchsia OS,对标鸿蒙取代 Android?

    谷歌称,Fuchsia 被设计为安全、可更新,具有包容性和实用性的生产级操作系统。 除了新的邮件列表,谷歌还发布了 Fuchsia 的技术路线图主要侧重于低级操作系统,例如“独立于驱动程序更新内核的驱动程序框架”和“Fuchsia 接口”。Fuchsia 的技术路线图表明,其许多初始子系

    2024年04月25日
    浏览(36)
  • 可靠的手机问题修复工具分享 - 修复各种 Android 系统问题

    一般来说,安卓手机都可以流畅运行。但不幸的是,有时您的Android手机可能无法正常运行,例如无响应、突然重启等。在这种情况下,您将需要Android手机维修软件。这些 Android 修复工具可以帮助您轻松解决此类问题,并还给您一部正常的 Android 手机。 事实上,你的Android系统

    2024年02月16日
    浏览(47)
  • Android 热修复核心原理

    dexopt 在 Dalvik 中虚拟机在加载一个dex文件时,对 dex 文件 进行 验证 和 优化的操作,其对 dex 文件的优化结果变成了 odex(Optimized dex) 文件,这个文件和 dex 文件很像,只是使用了一些优化操作码。 dex2oat ART 预先编译机制 ,在安装时对 dex 文件执行dexopt优化之后再将odex进行 AO

    2024年02月11日
    浏览(31)
  • Android 热修复

    1.Android热修复 热修复,就是对线上版本的静默更新。当APP发布上线之后,如果出现了严重的bug,通常需要重新发版来修复,但是重新走发布流程可能时间比较长,重新安装APP用户体验也不友好,所以出现了热修复,热修复就是通过发布一个插件,使APP运行的时候加载插件里面

    2023年04月08日
    浏览(45)
  • 快速修复应用程序中的问题的利器—— Android热修复

    热修复技术在Android开发中扮演着重要的角色,它可以帮助开发者在不需要重新发布应用程序的情况下修复已经上线的应用程序中的bug或者添加新的功能。 热修复(HotFix)是一种在运行时修复应用程序中的问题的技术。它可以通过动态加载补丁文件来修复已经上线的应用程序

    2024年02月13日
    浏览(30)
  • Android Architecture Components ——LiveData使用,android热修复视频

    小结:getApplication()即是全局的上下文 Activity中进行数据监听 import android.arch.lifecycle.MutableLiveData; import android.arch.lifecycle.Observer; import android.arch.lifecycle.ViewModelProviders; import android.support.annotation.Nullable; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log;

    2024年04月17日
    浏览(45)
  • 修复 Android 手机陷入恢复模式的 5 种方法

      您的手机卡在 Android Recovery 模式且无法退出此模式?无论您按什么按钮组合,甚至在取出并重新插入电池后重新启动手机,手机都会启动回到恢复模式吗? Android卡在recovery模式的情况并不罕见,各种品牌的Android手机都可能发生这种情况,比如三星、Oppo、华为、LG等。不过

    2024年02月22日
    浏览(45)
  • 如何利用路由器OS配置热点网关

    网关概念 网关编辑网关(Gateway)又称网间连接器、协议转换器。网关在网络层以上实现网络互连,是最复杂的网络互连设备,仅用于两个高层协议不同的网络互连。网关既可以用于广域网互连,也可以用于局域网互连。 网关是一种充当转换重任的计算机系统或设备。在使用不

    2024年02月07日
    浏览(54)
  • 如何给Mac OS 更新到指定版本系统

      1、在Apple网站,Apple - 技术支持 - 搜索 (中国),搜索指定的系统版本做下载 网址: 点击自己需要的版本,例如 Monterey 12   点击获取   即可看到系统里面有了    现在等待下载 重启即可

    2024年02月11日
    浏览(50)
  • Android性能优化之修复游戏中内存泄漏(java层)

    游戏在bugly上内存OOM越来越严重,因此,近期对内存进行优化。从java层的内存进行优化开始,通过LeakCannary或者adb shell 获取到内存快照,发现好几处内存泄漏点。 1.单例类持有Activity : 查看内存快照,该闪屏页面Activity(包含引用对象)可回收3.8M的内存; LeakCannary的内存分析也

    2024年02月15日
    浏览(61)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包