我在运行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
如何解决此问题?
解决这个问题还有另一种非常方便的方法——使用RxJava的并发功能。您可以在后台执行任何任务,并以非常方便的方式将结果发布到主线程,因此这些结果将被传递到处理链。
第一个经过验证的答案建议是使用AsynTask。是的,这是一个解决方案,但现在已经过时了,因为周围有新的工具。
String getUrl() {
return "SomeUrl";
}
private Object makeCallParseResponse(String url) {
return null;
//
}
private void processResponse(Object o) {
}
getUrl方法提供URL地址,它将在主线程上执行。
makeCallParseResponse(..)-执行实际工作
processResponse(..)-将处理主线程上的结果。
异步执行的代码如下:
rx.Observable.defer(new Func0<rx.Observable<String>>() {
@Override
public rx.Observable<String> call() {
return rx.Observable.just(getUrl());
}
})
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.io())
.map(new Func1<String, Object>() {
@Override
public Object call(final String s) {
return makeCallParseResponse(s);
}
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<Object>() {
@Override
public void call(Object o) {
processResponse(o);
}
},
new Action1<Throwable>() {
@Override
public void call(Throwable throwable) {
// Process error here, it will be posted on
// the main thread
}
});
与AsyncTask相比,此方法允许切换调度器任意次数(例如,在一个调度器上获取数据,并在另一个调度器中处理这些数据(例如,scheduler.computation()))。您还可以定义自己的调度器。
为了使用此库,请在build.gradle文件中包含以下行:
compile 'io.reactivex:rxjava:1.1.5'
compile 'io.reactivex:rxandroid:1.2.0'
最后一个依赖项包括对.mainThread()调度程序的支持。
RxJava有一本很棒的电子书。
主线程是UI线程,您不能在主线程中执行可能会阻止用户交互的操作。您可以通过两种方式解决此问题:
强制在主线程中执行任务,如下所示
StrictMode.ThreadPolicy threadPolicy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(threadPolicy);
或者创建一个简单的处理程序并根据需要更新主线程。
Runnable runnable;
Handler newHandler;
newHandler = new Handler();
runnable = new Runnable() {
@Override
public void run() {
try {
//update UI
} catch (Exception e) {
e.printStackTrace();
}
}
};
newHandler.post(runnable);
要停止线程,请使用:
newHandler.removeCallbacks(runnable);
有关更多信息,请查看:无痛线程