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

agxfikkp  于 2021-06-30  发布在  Java
关注(0)|答案(22)|浏览(284)

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

如何解决此问题?

wlwcrazw

wlwcrazw16#

该错误是由于在主线程中执行长时间运行的操作造成的,您可以使用asyntask或thread轻松地纠正该问题。您可以 checkout 此库asynchttpclient以获得更好的处理。

AsyncHttpClient client = new AsyncHttpClient();
client.get("http://www.google.com", new AsyncHttpResponseHandler() {

    @Override
    public void onStart() {
        // Called before a request is started
    }

    @Override
    public void onSuccess(int statusCode, Header[] headers, byte[] response) {
        // Called when response HTTP status is "200 OK"
    }

    @Override
    public void onFailure(int statusCode, Header[] headers, byte[] errorResponse, Throwable e) {
        // Called when response HTTP status is "4XX" (for example, 401, 403, 404)
    }

    @Override
    public void onRetry(int retryNo) {
        // Called when request is retried
    }
});
qnyhuwrf

qnyhuwrf17#

这个问题有两种解决办法。
1) 不要在主ui线程中编写网络调用,使用异步任务。
2) 在setcontentview(r.layout.activity\u main)之后,将下面的代码写入mainactivity文件;

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

以及下面的import语句。

import android.os.StrictMode;
ejk8hzay

ejk8hzay18#

在另一个线程上执行网络操作
例如:

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

并将其添加到androidmanifest.xml

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

js5cn81o19#

使用android注解是一种选择。它将允许您在后台线程中简单地运行任何方法:

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

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

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

siv3szwd

siv3szwd20#

您不应该在主线程(ui线程)上执行任何耗时的任务,比如任何网络操作、文件i/o或sqlite数据库操作。因此,对于这种操作,您应该创建一个工作线程,但问题是您不能从工作线程直接执行任何与ui相关的操作。为此,你必须使用 Handler 并通过 Message .
为了简化所有这些事情,android提供了各种方法,比如 AsyncTask , AsyncTaskLoader , CursorLoader 或者 IntentService . 所以你可以根据你的要求使用这些。

izkcnapc

izkcnapc21#

如果在主线程上执行的任何繁重任务花费太多时间,则会发生此异常。
为了避免这种情况,我们可以使用线程或执行器来处理它

Executors.newSingleThreadExecutor().submit(new Runnable() {
    @Override
    public void run() {
        // You can perform your task here.
    }
});
ruyhziif

ruyhziif22#

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

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

不建议这样做:使用 AsyncTask 接口。
两种方法的完整代码

相关问题