I got an error while running my Android project for RssReader.
Code:
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();
And it shows the below error:
android.os.NetworkOnMainThreadException
How can I fix this issue?
This exception is thrown when an application attempts to perform a networking operation on its main thread. Run your code in
AsyncTask
:How to execute the task:
In
MainActivity.java
file you can add this line within youroncreate()
methodDon't forget to add this to
AndroidManifest.xml
file:The error is due to executing long running operations in main thread,You can easily rectify the problem by using AsynTask or Thread. You can checkout this library AsyncHTTPClient for better handling.
You should not do any time-consuming task on the main thread (UI thread), like any network operation, file I/O, or SQLite database operations. So for this kind of operation, you should create a worker thread, but the problem is that you can not directly perform any UI related operation from your worker thread. For that, you have to use
Handler
and pass theMessage
.To simplify all these things, Android provides various ways, like
AsyncTask
,AsyncTaskLoader
,CursorLoader
orIntentService
. So you can use any of these according to your requirements.This happens in Android 3.0 and above. From Android 3.0 and above, they have restricted using network operations (functions that access the Internet) from running in the main thread/UI thread (what spawns from your on create and on resume methods in the activity).
This is to encourage using separate threads for network operations. See AsyncTask for more details on how to perform network activities the right way.
There are many great answers already on this question, but a lot of great libraries have come out since those answers were posted. This is intended as a kind of newbie-guide.
I will cover several use cases for performing network operations and a solution or two for each.
ReST over HTTP
Typically Json, can be XML or something else
Full API Access
Let's say you are writing an app that lets users track stock prices, interest rates and currecy exchange rates. You find an Json API that looks something like this:
Retrofit from Square
This is an excellent choice for an API with multiple endpoints and allows you to declare the ReST endpoints instead of having to code them individually as with other libraries like ion or Volley. (website: http://square.github.io/retrofit/)
How do you use it with the finances API?
build.gradle
Add these lines to your Module level buid.gradle:
FinancesApi.java
FinancesApiBuilder
FinancesFragment snippet
If your API requires an API Key or other header like a user token, etc. to be sent, Retrofit makes this easy (see this awesome answer for details: https://stackoverflow.com/a/42899766/1024412).
One off ReST API access
Let's say you're building a "mood weather" app that looks up the users GPS location and checks the current temperature in that area and tells them the mood. This type of app doesn't need to declare API endpoints; it just needs to be able to access one API endpoint.
Ion
This is a great library for this type of access.
Please read msysmilu's great answer (https://stackoverflow.com/a/28559884/1024412)
Load images via HTTP
Volley
Volley can also be used for ReST APIs, but due to the more complicated setup required I prefer to use Retrofit from Square as above (http://square.github.io/retrofit/)
Let's say you are building a social networking app and want to load profile pictures of friends.
build.gradle
Add this line to your Module level buid.gradle:
ImageFetch.java
Volley requires more setup than Retrofit. You will need to create a class like this to setup a RequestQueue, an ImageLoader and an ImageCache, but it's not too bad:
user_view_dialog.xml
Add the following to your layout xml file to add an image:
UserViewDialog.java
Add the following code to the onCreate method (Fragment, Activity) or the constructor (Dialog):
Picasso
Another excellent library from Square. Please see the site for some great examples: http://square.github.io/picasso/
RxAndroid
is another better alternative to this problem and it saves us from hassles of creating threads and then posting results on Android UI thread. We just need to specify threads on which tasks need to be executed and everything is handled internally.By specifiying
(Schedulers.io())
,RxAndroid will rungetFavoriteMusicShows()
on a different thread.By using
AndroidSchedulers.mainThread()
we want to observe this Observable on the UI thread, i.e. we want ouronNext()
callback to be called on the UI thread