我在运行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
如何解决此问题?
RxAndroid是解决这个问题的另一个更好的选择,它让我们省去了创建线程然后在Android UI线程上发布结果的麻烦。
我们只需要指定需要在哪些线程上执行任务,并且所有事情都在内部处理。
Observable<List<String>> musicShowsObservable = Observable.fromCallable(new Callable<List<String>>() {
@Override
public List<String> call() {
return mRestClient.getFavoriteMusicShows();
}
});
mMusicShowSubscription = musicShowsObservable
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<List<String>>() {
@Override
public void onCompleted() { }
@Override
public void onError(Throwable e) { }
@Override
public void onNext(List<String> musicShows) {
listMusicShows(musicShows);
}
});
通过指定(Schedulers.io()),RxAndroid将在不同的线程上运行getFavoriteMusicShows()。通过使用AndroidSchedulers.mainThread(),我们希望在UI线程上观察这个Observable,也就是说,我们希望我们的onNext()回调在UI线程中被调用。
谷歌不推荐Android 11中的Android AsyncTask API。
即使在主活动之外创建线程类,只要在main中调用它,也会得到相同的错误。调用必须在一个可运行的线程内,但如果您需要一些异步代码在后台执行或稍后在这里执行,您可以查看Kotlin和Java的一些替代方案:
*https://stackoverflow.com/questions/58767733/android-asynctask-api-deprecating-in-android-11-what-are-the-alternatives*
特别适合我的是mayank1513对上面链接中可运行线程的Java8实现的回答。代码如下:
new Thread(() -> {
// do background stuff here
runOnUiThread(()->{
// OnPostExecute stuff here
});
}).start();
但是,您可以先在代码的某个部分定义线程,然后在其他地方启动它,如下所示:
线程定义
Thread thread = new Thread(() -> {
// do background stuff here
runOnUiThread(()->{
// OnPostExecute stuff here
});
});
线程调用
thread.start();
我希望这可以让人省去看到不推荐的AsyncTask时的头疼。