我正在使用XmlPullParser从服务器解析文件,当然我在另一个线程中进行。我正在使用rxAndroid来处理线程,但它会引发NetworkOnMainThread
异常。请帮帮我。
public static List<ArticleModel> parseArticles(String get) {
try {
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
factory.setNamespaceAware(true);
XmlPullParser parser = factory.newPullParser();
URL url = new URL(get);
**parser.setInput(url.openStream(),null);** // HERE GOES THE EXCEPTION
int eventType = parser.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
String tagname = parser.getName();
switch (eventType) {
case XmlPullParser.START_TAG:
if (tagname.equalsIgnoreCase("article")) {
// create a new instance of employee
articleModel =new ArticleModel();
}
break;
case XmlPullParser.TEXT:
text = parser.getText();
break;
case XmlPullParser.END_TAG:
if (tagname.equalsIgnoreCase("article")) {
// add employee object to list
articleModelList.add(articleModel);
}else if (tagname.equalsIgnoreCase("id")) {
articleModel.setId(text);
} else if (tagname.equalsIgnoreCase("name")) {
articleModel.setName(text);
} else if (tagname.equalsIgnoreCase("image_url")) {
articleModel.setImage_url(text);
}
else if (tagname.equalsIgnoreCase("url")) {
articleModel.setUrl(text);
}
else if (tagname.equalsIgnoreCase("type")) {
articleModel.setType(text);
}
break;
default:
break;
}
eventType = parser.next();
}
} catch (XmlPullParserException e) {e.printStackTrace();}
catch (IOException e) {e.printStackTrace();}
return articleModelList;
}
这是我的RX方法:
public void getArticles(String get, final boolean needRefresh) throws IOException {
Observable.just(XmlPullParserHanlder.parseArticles(get))
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<List<ArticleModel>>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
Log.i("SIZE", "onNext: "+ e.toString());
}
@Override
public void onNext(List<ArticleModel> articleModels) {
}
});
}
答案 0 :(得分:1)
问题不在于从UI线程调用Rx方法。问题是你在非UI线程中进行了parseArticles()
的网络操作。
您可以尝试这种方法 -
public void getArticles(String get, final boolean needRefresh) throws IOException {
Observable.create(new Observable.OnSubscribe<List< ArticleModel >>() {
@Override
public void call(Subscriber<? super List< ArticleModel >> subscriber) {
subscriber.onNext(parseArticles(get));
subscriber.onCompleted();
}
}).subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<List<ArticleModel>>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
Log.i("SIZE", "onNext: "+ e.toString());
}
@Override
public void onNext(List<ArticleModel> articleModels) {
}
});
}
}
答案 1 :(得分:0)
您使用.subscribeOn(Schedulers.newThread())
这很好,但这是Observable.just(XmlPullParserHanlder.parseArticles(get))
的结果,而不是XmlPullParserHanlder.parseArticles(get)
方法本身的结果。试试这样的事情
Observable.just(get)
.subscribeOn(Schedulers.newThread())
.map(url -> XmlPullParserHanlder.parseArticles(url))
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<List<ArticleModel>>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
Log.i("SIZE", "onNext: "+ e.toString());
}
@Override
public void onNext(List<ArticleModel> articleModels) {
}
});