How do I fix android.os.NetworkOnMainThreadException?
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?
java

|
show 3 more comments
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?
java

122
Read this blog post on the NetworkOnMainThreadException for more information. It explains why this occurs on Android 3.0 and above.
– Adrian Monk
Aug 7 '12 at 12:38
4
To be on rite track first read about the Network Requests in android then i would recommend to study "Volley".
– Anuj Sharma
Jan 23 '14 at 6:39
2
There are many alternative libraries that solve this issue. Many are listed at the bottom of this page. If you got more, we take them :)
– Snicolas
Feb 11 '14 at 22:55
You need to run internet activities on a thread separate from main (UI) thread
– Naveed Ahmad
Oct 30 '14 at 20:44
stackoverflow.com/questions/16439587/… above link is good
– nguyenvangiangbn
Jan 1 '15 at 5:12
|
show 3 more comments
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?
java

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?
java

java

edited Feb 3 '18 at 14:49


Ali Esa Assadi
765711
765711
asked Jun 14 '11 at 12:02
bejoy georgebejoy george
11.2k51315
11.2k51315
122
Read this blog post on the NetworkOnMainThreadException for more information. It explains why this occurs on Android 3.0 and above.
– Adrian Monk
Aug 7 '12 at 12:38
4
To be on rite track first read about the Network Requests in android then i would recommend to study "Volley".
– Anuj Sharma
Jan 23 '14 at 6:39
2
There are many alternative libraries that solve this issue. Many are listed at the bottom of this page. If you got more, we take them :)
– Snicolas
Feb 11 '14 at 22:55
You need to run internet activities on a thread separate from main (UI) thread
– Naveed Ahmad
Oct 30 '14 at 20:44
stackoverflow.com/questions/16439587/… above link is good
– nguyenvangiangbn
Jan 1 '15 at 5:12
|
show 3 more comments
122
Read this blog post on the NetworkOnMainThreadException for more information. It explains why this occurs on Android 3.0 and above.
– Adrian Monk
Aug 7 '12 at 12:38
4
To be on rite track first read about the Network Requests in android then i would recommend to study "Volley".
– Anuj Sharma
Jan 23 '14 at 6:39
2
There are many alternative libraries that solve this issue. Many are listed at the bottom of this page. If you got more, we take them :)
– Snicolas
Feb 11 '14 at 22:55
You need to run internet activities on a thread separate from main (UI) thread
– Naveed Ahmad
Oct 30 '14 at 20:44
stackoverflow.com/questions/16439587/… above link is good
– nguyenvangiangbn
Jan 1 '15 at 5:12
122
122
Read this blog post on the NetworkOnMainThreadException for more information. It explains why this occurs on Android 3.0 and above.
– Adrian Monk
Aug 7 '12 at 12:38
Read this blog post on the NetworkOnMainThreadException for more information. It explains why this occurs on Android 3.0 and above.
– Adrian Monk
Aug 7 '12 at 12:38
4
4
To be on rite track first read about the Network Requests in android then i would recommend to study "Volley".
– Anuj Sharma
Jan 23 '14 at 6:39
To be on rite track first read about the Network Requests in android then i would recommend to study "Volley".
– Anuj Sharma
Jan 23 '14 at 6:39
2
2
There are many alternative libraries that solve this issue. Many are listed at the bottom of this page. If you got more, we take them :)
– Snicolas
Feb 11 '14 at 22:55
There are many alternative libraries that solve this issue. Many are listed at the bottom of this page. If you got more, we take them :)
– Snicolas
Feb 11 '14 at 22:55
You need to run internet activities on a thread separate from main (UI) thread
– Naveed Ahmad
Oct 30 '14 at 20:44
You need to run internet activities on a thread separate from main (UI) thread
– Naveed Ahmad
Oct 30 '14 at 20:44
stackoverflow.com/questions/16439587/… above link is good
– nguyenvangiangbn
Jan 1 '15 at 5:12
stackoverflow.com/questions/16439587/… above link is good
– nguyenvangiangbn
Jan 1 '15 at 5:12
|
show 3 more comments
50 Answers
50
active
oldest
votes
1 2
next
This exception is thrown when an application attempts to perform a networking operation on its main thread. Run your code in AsyncTask
:
class RetrieveFeedTask extends AsyncTask<String, Void, RSSFeed> {
private Exception exception;
protected RSSFeed doInBackground(String... urls) {
try {
URL url = new URL(urls[0]);
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();
} catch (Exception e) {
this.exception = e;
return null;
} finally {
is.close();
}
}
protected void onPostExecute(RSSFeed feed) {
// TODO: check this.exception
// TODO: do something with the feed
}
}
How to execute the task:
In MainActivity.java
file you can add this line within your oncreate()
method
new RetrieveFeedTask().execute(urlToRssFeed);
Don't forget to add this to AndroidManifest.xml
file:
<uses-permission android:name="android.permission.INTERNET"/>
31
I think it is worth noting here that the code snippet above is supposed to be a subclass (inner class), preferably private. That way when the AsyncTask finishes, you can still manipulate the innards of your class.
– dyslexicanaboko
Jul 22 '12 at 5:57
3
Actually i did the Same thing as u mentioned above but m facing this error java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
– Dhruv Tyagi
Aug 30 '16 at 11:08
44
This is exactly the wrong answer. I come across this all the time in peoples code, and its annoying to have to fix it all the time. AsyncTask should not be used for network activity, because it's tied to the activity, but not the activity lifecycle. Rotating the device with this task is running will cause an exception and crash your app. Use an IntentService that drops data in the sqlite database instead.
– Brill Pappin
Sep 9 '16 at 19:08
1
Caution, AsyncTask is often used for per activity network operations when it should not be. its lifecycle is not in sync with the activity. For fetching data, you should use an IntentService and the database behind the view.
– Brill Pappin
Oct 5 '16 at 21:24
1
@BrillPappin I am glad that i explored the comments, otherwise i would have gone with Async Task thanks.
– Shivam Pokhriyal
Sep 5 '18 at 5:26
|
show 11 more comments
You should almost always run network operations on a thread or as an asynchronous task.
But it is possible to remove this restriction and you override the default behavior, if you are willing to accept the consequences.
Add:
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
In your class,
and
ADD this permission in android manifest.xml file:
<uses-permission android:name="android.permission.INTERNET"/>
Consequences:
Your app will (in areas of spotty internet connection) become unresponsive and lock up, the user perceives slowness and has to do a force kill, and you risk the activity manager killing your app and telling the user that the app has stopped.
Android has some good tips on good programming practices to design for responsiveness:
http://developer.android.com/reference/android/os/NetworkOnMainThreadException.html
432
This is a very bad idea. the solution is to avoid network IO on main thread (as the accepted answer shows).
– MByD
May 14 '12 at 14:10
66
With this you only hide your real problem.
– Alex
Jun 18 '12 at 6:44
24
@TwistedUmbrella The AsyncTask does not add a page of code, it adds 6 lines (class declaration, override annotation,doInBackground
declaration, 2 closing brackets and a call toexecute()
). On the other hand, even a single fetch from a site as you mention brings a significant lag in the UI responsiveness. Don't be lazy.
– Zoltán
Sep 4 '12 at 9:39
50
@TwistedUmbrella Don't be silly. That is how bad applications are made. Whether it is downloading a text file or an image gallery, you should follow best practices. And running network IO on main thread is not a best practice.
– States
Nov 1 '12 at 1:23
79
Upvoted. This answer is correct, and for the many programmers who are neither naive nor stupid, but who simply require a SYNCHRONOUS (i.e.: this must block the app) call, this is exactly what's needed. I'm more than happy that Android throws the exception by default (IMHO it's a very "helpful" thing to do!) - but I'm equally happy to say "thanks, but - this is actually what I intended" and to override it.
– Adam
May 1 '13 at 6:48
|
show 42 more comments
I solved this problem using a new Thread
.
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
try {
//Your code goes here
} catch (Exception e) {
e.printStackTrace();
}
}
});
thread.start();
6
Instead of creating a new thread each time you want to perform a network operation, you could use a single thread executor service too.
– Alex Lockwood
Jan 27 '13 at 18:06
56
Simple but dangerous. The anonymous Runnable has an implicit reference to the enclosing class (e.g. your Activity or Fragment), preventing it from being garbage collected until the thread completes. You should at least set the priority to Process.BACKGROUND, else this thread will run at the same priority as the main/ui thread, contending with lifecycle methods and ui frame rates (watch out for warnings in log from the choreographer).
– Stevie
Jun 19 '14 at 12:39
@Stevie how to set the priority? neither runnble nor the executorService have such a setter method
– J. K.
May 31 '15 at 13:26
1
@J.K. Supply your ExecutorService with a custom ThreadFactory and call Thread.setPriority on the thread before returning it.
– Stevie
Jun 1 '15 at 19:14
Setting priority for something that is intended to do a network call (which will block) seems overkill.
– john16384
Jan 27 '16 at 13:09
|
show 2 more comments
You cannot perform network I/O on the UI thread on Honeycomb. Technically, it is possible on earlier versions of Android, but it is a really bad idea as it will cause your app to stop responding, and can result in the OS killing your app for being badly behaved. You'll need to run a background process or use AsyncTask to perform your network transaction on a background thread.
There is an article about Painless Threading on the Android developer site which is a good introduction to this, and it will provide you with a much better depth of an answer than can be realistically provided here.
add a comment |
The accepted answer has some significant down-sides. It is not advisable to use AsyncTask for networking unless you really know what you are doing. Some of the down-sides include:
- AsyncTask's created as non-static inner classes have an implicit reference to the enclosing Activity object, its context, and the entire View hierarchy created by that activity. This reference prevents the Activity from being garbage collected until the AsyncTask's background work completes. If the user's connection is slow, and/or the download is large, these short-term memory leaks can become a problem - for example if the orientation changes several times (and you don't cancel the executing tasks), or the user navigates away from the Activity.
- AsyncTask has different execution characteristics depending on the platform it executes on: prior to API level 4 AsyncTasks execute serially on a single background thread; from API level 4 through API level 10, AsyncTasks execute on a pool of up to 128 threads; from API level 11 onwards AsyncTask executes serially on a single background thread (unless you use the overloaded
executeOnExecutor
method and supply an alternative executor). Code that works fine when run serially on ICS may break when executed concurrently on Gingerbread, say, if you have inadvertent order-of-execution dependencies.
If you want to avoid short-term memory leaks, have well defined execution characteristics across all platforms, and have a base to build really robust network handling, you might want to consider:
- Using a library that does a nice job of this for you - there's a nice comparison of networking libs in this question, or
- Using a
Service
orIntentService
instead, perhaps with aPendingIntent
to return the result via the Activity'sonActivityResult
method.
IntentService approach
Down-sides:
- More code and complexity than
AsyncTask
, though not as much as you might think - Will queue requests and run them on a single background thread. You can easily control this by replacing
IntentService
with an equivalentService
implementation, perhaps like this one. - Um, I can't think of any others right now actually
Up-sides:
- Avoids the short-term memory leak problem
- If your activity restarts while network operations are in-flight it can still receive the result of the download via its
onActivityResult
method - Better platform than AsyncTask to build and re-use robust networking code. Example: if you need to do an important upload, you could do it from
AsyncTask
in anActivity
, but if the user context-switches out of the app to take a phone-call, the system may kill the app before the upload completes. It is less likely to kill an application with an activeService
. - If you use your own concurrent version of
IntentService
(like the one I linked above) you can control the level of concurrency via theExecutor
.
Implementation summary
You can implement an IntentService
to perform downloads on a single background thread quite easily.
Step 1: Create an IntentService
to perform the download. You can tell it what to download via Intent
extra's, and pass it a PendingIntent
to use to return the result to the Activity
:
import android.app.IntentService;
import android.app.PendingIntent;
import android.content.Intent;
import android.util.Log;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
public class DownloadIntentService extends IntentService {
private static final String TAG = DownloadIntentService.class.getSimpleName();
public static final String PENDING_RESULT_EXTRA = "pending_result";
public static final String URL_EXTRA = "url";
public static final String RSS_RESULT_EXTRA = "url";
public static final int RESULT_CODE = 0;
public static final int INVALID_URL_CODE = 1;
public static final int ERROR_CODE = 2;
private IllustrativeRSSParser parser;
public DownloadIntentService() {
super(TAG);
// make one and re-use, in the case where more than one intent is queued
parser = new IllustrativeRSSParser();
}
@Override
protected void onHandleIntent(Intent intent) {
PendingIntent reply = intent.getParcelableExtra(PENDING_RESULT_EXTRA);
InputStream in = null;
try {
try {
URL url = new URL(intent.getStringExtra(URL_EXTRA));
IllustrativeRSS rss = parser.parse(in = url.openStream());
Intent result = new Intent();
result.putExtra(RSS_RESULT_EXTRA, rss);
reply.send(this, RESULT_CODE, result);
} catch (MalformedURLException exc) {
reply.send(INVALID_URL_CODE);
} catch (Exception exc) {
// could do better by treating the different sax/xml exceptions individually
reply.send(ERROR_CODE);
}
} catch (PendingIntent.CanceledException exc) {
Log.i(TAG, "reply cancelled", exc);
}
}
}
Step 2: Register the service in the manifest:
<service
android:name=".DownloadIntentService"
android:exported="false"/>
Step 3: Invoke the service from the Activity, passing a PendingResult object which the Service will use to return the result:
PendingIntent pendingResult = createPendingResult(
RSS_DOWNLOAD_REQUEST_CODE, new Intent(), 0);
Intent intent = new Intent(getApplicationContext(), DownloadIntentService.class);
intent.putExtra(DownloadIntentService.URL_EXTRA, URL);
intent.putExtra(DownloadIntentService.PENDING_RESULT_EXTRA, pendingResult);
startService(intent);
Step 4: Handle the result in onActivityResult:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == RSS_DOWNLOAD_REQUEST_CODE) {
switch (resultCode) {
case DownloadIntentService.INVALID_URL_CODE:
handleInvalidURL();
break;
case DownloadIntentService.ERROR_CODE:
handleError(data);
break;
case DownloadIntentService.RESULT_CODE:
handleRSS(data);
break;
}
handleRSS(data);
}
super.onActivityResult(requestCode, resultCode, data);
}
A github project containing a complete working Android-Studio/gradle project is available here.
IntentService is the correct way to do this, not uprooting because AsyncTask is exactly the way not to do it.
– Brill Pappin
Sep 10 '16 at 14:59
2
@BrillPappin I almost entirely agree and have re-worded to emphasize the drawbacks of AsyncTask. (I still think there are a very small number of cases where - if you really know what you are doing - it might be OK to use AsyncTask, but the accepted answer doesn't point out any drawbacks and is way too popular for the good of Android).
– Stevie
Mar 13 '17 at 12:56
Do you actually needIllustrativeRSS
? What if you're not working with RSS stuff?
– Cullub
Apr 14 '18 at 19:13
add a comment |
- Do not use strictMode (only in debug mode)
- Do not change SDK version
- Do not use a separate thread
Use Service or AsyncTask
See also Stack Overflow question:
android.os.NetworkOnMainThreadException sending an email from Android
7
Perhaps worth stressing the point that if you use a Service you will still need to create a separate thread - Service callbacks run on the main thread. An IntentService, on the other hand, runs its onHandleIntent method on a background thread.
– Stevie
Jan 22 '14 at 8:33
you should not use an AsyncTask for long running operations! Guidelines specify 2 to 3 seconds max.
– Dage
Feb 4 '14 at 10:41
add a comment |
Do the network actions on another thread
For Example:
new Thread(new Runnable(){
@Override
public void run() {
// Do network action in this function
}
}).start();
And add this to AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET"/>
4
But how can we find out when the thread finishes in this so that we can carry out the next set of tasks in the UI thread? The AsyncTask provides the facility to do that. Is there a way to do the same using runnable threads?
– Piyush Soni
Jan 4 '14 at 23:30
1
It will process your code step by step, so in the end of the code is finish, you need to use handler back to UI thread
– henry4343
Jan 5 '14 at 2:18
mobileorchard.com/…
– henry4343
Jan 6 '14 at 0:50
You can use async task or intent service, because it's execute on worker thread.
– Chetan Chaudhari
Apr 19 '17 at 20:05
add a comment |
You disable the strict mode using following code:
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy =
new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
This is not recommended: use the AsyncTask
interface.
Full code for both the methods
1
Yes ANR error would be come. means App not responding with in 5 sec.
– Muhammad Mubashir
May 6 '13 at 11:23
7
This is a really bad answer. You should not change the thread's policy but to write better code: do not make network operations on main thread!
– shkschneider
Aug 29 '13 at 15:01
6
Not good, but useful for POC / Debugging
– hB0
Nov 5 '13 at 15:26
@Sandeep You and other viewers should read this too. stackoverflow.com/a/18335031/3470479
– Prakhar1001
Sep 15 '16 at 14:06
add a comment |
Network-based operations cannot be run on the main thread. You need to run all network-based tasks on a child thread or implement AsyncTask.
This is how you run a task in a child thread:
new Thread(new Runnable(){
@Override
public void run() {
try {
// Your implementation goes here
}
catch (Exception ex) {
ex.printStackTrace();
}
}
}).start();
Anonymous Runnable is NOT the best way, since it has an implicit reference to the enclosing class and preventing it from being GC ed until the thread completes! Also this thread will run at the Same Priority as the main/US thread, contending with lifecycle methods and UI frame rates!
– Yousha Aleayoub
Mar 12 '16 at 13:18
add a comment |
Put your code inside:
new Thread(new Runnable(){
@Override
public void run() {
try {
// Your implementation
}
catch (Exception ex) {
ex.printStackTrace();
}
}
}).start();
Or:
class DemoTask extends AsyncTask<Void, Void, Void> {
protected Void doInBackground(Void... arg0) {
//Your implementation
}
protected void onPostExecute(Void result) {
// TODO: do something with the feed
}
}
Second one ll be best than first for api above than 11
– Rohit Goswami
Jul 28 '14 at 10:52
read the comment under: stackoverflow.com/a/21107128/1429432
– Yousha Aleayoub
Mar 12 '16 at 13:19
Async Work on most case
– Ajay Pandya
Dec 9 '16 at 10:15
add a comment |
Using Android Annotations is an option. It will allow you to simply run any method in a background thread:
// normal method
private void normal() {
doSomething(); // do something in background
}
@Background
protected void doSomething()
// run your networking code here
}
Note, that although it provides benefits of simplicity and readability, it has its disadvantages.
1
what are the disadvantages?
– Gavriel
Aug 15 '15 at 20:00
5
@Gavriel it creates duplicates of everything you annotate, whether it's a method, activity, fragment, singleton etc, so there is twice as much code and it takes longer to compile it. It may also have some issues due to bugs in the library. Debugging and finding errors would become more difficult.
– Oleksiy
Aug 19 '15 at 1:30
add a comment |
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.
add a comment |
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 the Message
.
To simplify all these things, Android provides various ways, like AsyncTask
, AsyncTaskLoader
, CursorLoader
or IntentService
. So you can use any of these according to your requirements.
add a comment |
The top answer of spektom works perfect.
If you are writing the AsyncTask
inline and not extending as a class, and on top of this, if there is a need to get a response out of the AsyncTask
, one can use the get()
method as below.
RSSFeed feed = new RetreiveFeedTask().execute(urlToRssFeed).get();
(From his example.)
5
usingget()
is a bad idea ... it makes AsyncTask "sync" again
– Selvin
Sep 17 '13 at 15:29
Is there a better different way out of it? @Selvin
– sivag1
Sep 20 '13 at 20:50
2
I think you could info the main thread about the result.For example,send a broadcast to main thread including the result.
– Chine Gary
Feb 10 '15 at 2:35
add a comment |
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.
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
}
});
add a comment |
This is only thrown for applications targeting the Honeycomb SDK or higher. Applications targeting earlier SDK versions are allowed to do networking on their main event loop threads.
The error is the SDK warning!
add a comment |
For me it was this:
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="10" />
The device I was testing my app on was 4.1.2 which is SDK Version 16!
Make the sure the target version is the same as your Android Target Library. If you are unsure what your target library is, right click your Project -> Build Path -> Android, and it should be the one that is ticked.
Also, as others have mentioned, include the correct permissions to access the Internet:
<uses-permission android:name="android.permission.INTERNET"/>
11
Let me explain you what you are doing here:NetworkOnMainThreadException
is the Guardian which is telling you: do not shoot at your own foot ... your solution is: let's go back to the past when there was no Guardian - now i can shoot at my foot freely
– Selvin
Sep 17 '13 at 15:36
1
I took this approach, too, and didn't have any problems. Guardian is too fussy sometimes.
– FractalBob
Oct 25 '13 at 19:36
add a comment |
Just to spell out something explicitly:
The main thread is basically the UI thread.
So saying that you cannot do networking operations in the main thread means you cannot do networking operations in the UI thread, which means you cannot do networking operations in a *runOnUiThread(new Runnable() { ... }*
block inside some other thread, either.
(I just had a long head-scratching moment trying to figure out why I was getting that error somewhere other than my main thread. This was why; this thread helped; and hopefully this comment will help someone else.)
add a comment |
This exception occurs due to any heavy task performed on the main thread if that performing task takes too much time.
To avoid this, we can handle it using threads or executers
Executors.newSingleThreadExecutor().submit(new Runnable() {
@Override
public void run() {
// You can perform your task here.
}
});
add a comment |
Use this in Your Activity
btnsub.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
//Initialize soap request + add parameters
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME1);
//Use this to add parameters
request.addProperty("pincode", txtpincode.getText().toString());
request.addProperty("bg", bloodgroup.getSelectedItem().toString());
//Declare the version of the SOAP request
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.setOutputSoapObject(request);
envelope.dotNet = true;
try {
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
//this is the actual part that will call the webservice
androidHttpTransport.call(SOAP_ACTION1, envelope);
// Get the SoapResult from the envelope body.
SoapObject result = (SoapObject) envelope.getResponse();
Log.e("result data", "data" + result);
SoapObject root = (SoapObject) result.getProperty(0);
// SoapObject s_deals = (SoapObject) root.getProperty(0);
// SoapObject s_deals_1 = (SoapObject) s_deals.getProperty(0);
//
System.out.println("********Count : " + root.getPropertyCount());
value = new ArrayList<Detailinfo>();
for (int i = 0; i < root.getPropertyCount(); i++) {
SoapObject s_deals = (SoapObject) root.getProperty(i);
Detailinfo info = new Detailinfo();
info.setFirstName(s_deals.getProperty("Firstname").toString());
info.setLastName(s_deals.getProperty("Lastname").toString());
info.setDOB(s_deals.getProperty("DOB").toString());
info.setGender(s_deals.getProperty("Gender").toString());
info.setAddress(s_deals.getProperty("Address").toString());
info.setCity(s_deals.getProperty("City").toString());
info.setState(s_deals.getProperty("State").toString());
info.setPinecode(s_deals.getProperty("Pinecode").toString());
info.setMobile(s_deals.getProperty("Mobile").toString());
info.setEmail(s_deals.getProperty("Email").toString());
info.setBloodgroup(s_deals.getProperty("Bloodgroup").toString());
info.setAdddate(s_deals.getProperty("Adddate").toString());
info.setWaight(s_deals.getProperty("waight").toString());
value.add(info);
}
} catch (Exception e) {
e.printStackTrace();
}
Intent intent = new Intent(getApplicationContext(), ComposeMail.class);
//intent.putParcelableArrayListExtra("valuesList", value);
startActivity(intent);
}
}).start();
}
});
add a comment |
In simple words,
DO NOT DO NETWORK WORK IN THE UI THREAD
For example, if you do an HTTP request, that is a network action.
Solution:
- You have to create a new Thread
Or use AsyncTask class
Way:
Put all your works inside
run()
method of new thread
OrdoInBackground()
method of AsyncTask class.
But:
When you get something from Network response and want to show it on your view (like display response message in TextView), you need to return back to the UI thread.
If you don't do it, you will get ViewRootImpl$CalledFromWrongThreadException
.
How to?
- While using AsyncTask, update view from
onPostExecute()
method
Or callrunOnUiThread()
method and update view inside therun()
method.
add a comment |
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:
http://api.example.com/stocks //ResponseWrapper<String> object containing a list of Srings with ticker symbols
http://api.example.com/stocks/$symbol //Stock object
http://api.example.com/stocks/$symbol/prices //PriceHistory<Stock> object
http://api.example.com/currencies //ResponseWrapper<String> object containing a list of currency abbreviation
http://api.example.com/currencies/$currency //Currency object
http://api.example.com/currencies/$id1/values/$id2 //PriceHistory<Currency> object comparing the prices of the first currency (id1) to the second (id2)
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:
implementation 'com.squareup.retrofit2:retrofit:2.3.0' //retrofit library, current as of September 21, 2017
implementation 'com.squareup.retrofit2:converter-gson:2.3.0' //gson serialization and deserialization support for retrofit, version must match retrofit version
FinancesApi.java
public interface FinancesApi {
@GET("stocks")
Call<ResponseWrapper<String>> listStocks();
@GET("stocks/{symbol}")
Call<Stock> getStock(@Path("symbol")String tickerSymbol);
@GET("stocks/{symbol}/prices")
Call<PriceHistory<Stock>> getPriceHistory(@Path("symbol")String tickerSymbol);
@GET("currencies")
Call<ResponseWrapper<String>> listCurrencies();
@GET("currencies/{symbol}")
Call<Currency> getCurrency(@Path("symbol")String currencySymbol);
@GET("currencies/{symbol}/values/{compare_symbol}")
Call<PriceHistory<Currency>> getComparativeHistory(@Path("symbol")String currency, @Path("compare_symbol")String currencyToPriceAgainst);
}
FinancesApiBuilder
public class FinancesApiBuilder {
public static FinancesApi build(String baseUrl){
return new Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(FinancesApi.class);
}
}
FinancesFragment snippet
FinancesApi api = FinancesApiBuilder.build("http://api.example.com/"); //trailing '/' required for predictable behavior
api.getStock("INTC").enqueue(new Callback<Stock>(){
@Override
public void onResponse(Call<Stock> stockCall, Response<Stock> stockResponse){
Stock stock = stockCall.body();
//do something with the stock
}
@Override
public void onResponse(Call<Stock> stockCall, Throwable t){
//something bad happened
}
}
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:
implementation 'com.android.volley:volley:1.0.0'
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:
public class ImageFetch {
private static ImageLoader imageLoader = null;
private static RequestQueue imageQueue = null;
public static ImageLoader getImageLoader(Context ctx){
if(imageLoader == null){
if(imageQueue == null){
imageQueue = Volley.newRequestQueue(ctx.getApplicationContext());
}
imageLoader = new ImageLoader(imageQueue, new ImageLoader.ImageCache() {
Map<String, Bitmap> cache = new HashMap<String, Bitmap>();
@Override
public Bitmap getBitmap(String url) {
return cache.get(url);
}
@Override
public void putBitmap(String url, Bitmap bitmap) {
cache.put(url, bitmap);
}
});
}
return imageLoader;
}
}
user_view_dialog.xml
Add the following to your layout xml file to add an image:
<com.android.volley.toolbox.NetworkImageView
android:id="@+id/profile_picture"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
app:srcCompat="@android:drawable/spinner_background"/>
UserViewDialog.java
Add the following code to the onCreate method (Fragment, Activity) or the constructor (Dialog):
NetworkImageView profilePicture = view.findViewById(R.id.profile_picture);
profilePicture.setImageUrl("http://example.com/users/images/profile.jpg", ImageFetch.getImageLoader(getContext());
Picasso
Another excellent library from Square. Please see the site for some great examples: http://square.github.io/picasso/
this should be the better answer than the original one as it simplifies the implementation of networking on android in the present world 2017, and most of the real world application uses very good libraries like these.
– Rakibul Haq
Nov 28 '17 at 11:46
add a comment |
Although above there is a huge solution pool, no one mentioned com.koushikdutta.ion
: https://github.com/koush/ion
It's also asynchronous and very simple to use:
Ion.with(context)
.load("http://example.com/thing.json")
.asJsonObject()
.setCallback(new FutureCallback<JsonObject>() {
@Override
public void onCompleted(Exception e, JsonObject result) {
// do stuff with the result or error
}
});
add a comment |
New Thread
and AsyncTask solutions have been explained already.
AsyncTask
should ideally be used for short operations. Normal Thread
is not preferable for Android.
Have a look at alternate solution using HandlerThread and Handler
HandlerThread
Handy class for starting a new thread that has a looper. The looper can then be used to create handler classes. Note that
start()
must still be called.
Handler:
A Handler allows you to send and process Message and Runnable objects associated with a thread's MessageQueue. Each Handler instance is associated with a single thread and that thread's message queue. When you create a new Handler, it is bound to the thread / message queue of the thread that is creating it -- from that point on, it will deliver messages and runnables to that message queue and execute them as they come out of the message queue.
Solution:
Create
HandlerThread
Call
start()
onHandlerThread
Create
Handler
by gettingLooper
fromHanlerThread
Embed your Network operation related code in
Runnable
objectSubmit
Runnable
task toHandler
Sample code snippet, which address NetworkOnMainThreadException
HandlerThread handlerThread = new HandlerThread("URLConnection");
handlerThread.start();
handler mainHandler = new Handler(handlerThread.getLooper());
Runnable myRunnable = new Runnable() {
@Override
public void run() {
try {
Log.d("Ravi", "Before IO call");
URL page = new URL("http://www.google.com");
StringBuffer text = new StringBuffer();
HttpURLConnection conn = (HttpURLConnection) page.openConnection();
conn.connect();
InputStreamReader in = new InputStreamReader((InputStream) conn.getContent());
BufferedReader buff = new BufferedReader(in);
String line;
while ( (line = buff.readLine()) != null) {
text.append(line + "n");
}
Log.d("Ravi", "After IO call");
Log.d("Ravi",text.toString());
}catch( Exception err){
err.printStackTrace();
}
}
};
mainHandler.post(myRunnable);
Pros of using this approach:
- Creating new
Thread/AsyncTask
for each network operation is expensive. TheThread/AsyncTask
will be destroyed and re-created for next Network operations. But withHandler
andHandlerThread
approach, you can submit many network operations (as Runnable tasks) to singleHandlerThread
by usingHandler
.
This shall be the correct answer.
– Thecave3
2 days ago
add a comment |
This works. Just made Dr.Luiji's answer a little simpler.
new Thread() {
@Override
public void run() {
try {
//Your code goes here
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
add a comment |
On Android, network operations cannot be run on the main thread. You can use Thread, AsyncTask (short-running tasks), Service (long-running tasks) to do network operations.
add a comment |
Accessing network resources from the main (UI) thread cause this exception. Use a separate thread or AsyncTask for accessing a network resource to avoid this problem.
add a comment |
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.
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);
}
});
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
add a comment |
You are not allowed to implement network operations on the UI thread on Android. You will have to use AsyncTask class to perform network related operations like sending API request, downloading image from a URL, etc. and using callback methods of AsyncTask, you can get you result in onPostExecute menthod and you will be in the UI thread and you can populate UI with data from web service or something like that.
Example: Suppose you want to download image from an URL: https://www.samplewebsite.com/sampleimage.jpg
Solution using AsyncTask:
are respectively.
public class MyDownloader extends AsyncTask<String,Void,Bitmap>
{
@Override
protected void onPreExecute() {
// Show progress dialog
super.onPreExecute();
}
@Override
protected void onPostExecute(Bitmap bitmap) {
//Populate Ui
super.onPostExecute(bitmap);
}
@Override
protected Bitmap doInBackground(String... params) {
// Open URL connection read bitmaps and return form here
return result;
}
@Override
protected void onProgressUpdate(Void... values) {
// Show progress update
super.onProgressUpdate(values);
}
}
}
Note: Do not forget to add the Internet permission in the Android manifest file. It will work like a charm. :)
add a comment |
There is another very convenient way for tackling this issue - use rxJava's concurrency capabilities. You can execute any task in background and post results to main thread in a very convenient way, so these results will be handed to processing chain.
The first verified answer advice is to use AsynTask. Yes, this is a solution, but it is obsolete nowadays, because there are new tools around.
String getUrl() {
return "SomeUrl";
}
private Object makeCallParseResponse(String url) {
return null;
//
}
private void processResponse(Object o) {
}
The getUrl method provides the URL address, and it will be executed on the main thread.
makeCallParseResponse(..) - does actual work
processResponse(..) - will handle result on main thread.
The code for asynchronous execution will look like:
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
}
});
Compared to AsyncTask, this method allow to switch schedulers an arbitrary number of times (say, fetch data on one scheduler and process those data on another (say, Scheduler.computation()). You can also define you own schedulers.
In order to use this library, include following lines into you build.gradle file:
compile 'io.reactivex:rxjava:1.1.5'
compile 'io.reactivex:rxandroid:1.2.0'
The last dependency includes support for the .mainThread() scheduler.
There is an excellent ebook for rx-java.
quite an extensive approach it would to be schedule by our own and i don't know why we should if it is already being an option on Android side?
– Prakhar1001
Sep 15 '16 at 14:10
add a comment |
1 2
next
protected by Jorgesys Jan 28 '14 at 18:29
Thank you for your interest in this question.
Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).
Would you like to answer one of these unanswered questions instead?
50 Answers
50
active
oldest
votes
50 Answers
50
active
oldest
votes
active
oldest
votes
active
oldest
votes
1 2
next
This exception is thrown when an application attempts to perform a networking operation on its main thread. Run your code in AsyncTask
:
class RetrieveFeedTask extends AsyncTask<String, Void, RSSFeed> {
private Exception exception;
protected RSSFeed doInBackground(String... urls) {
try {
URL url = new URL(urls[0]);
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();
} catch (Exception e) {
this.exception = e;
return null;
} finally {
is.close();
}
}
protected void onPostExecute(RSSFeed feed) {
// TODO: check this.exception
// TODO: do something with the feed
}
}
How to execute the task:
In MainActivity.java
file you can add this line within your oncreate()
method
new RetrieveFeedTask().execute(urlToRssFeed);
Don't forget to add this to AndroidManifest.xml
file:
<uses-permission android:name="android.permission.INTERNET"/>
31
I think it is worth noting here that the code snippet above is supposed to be a subclass (inner class), preferably private. That way when the AsyncTask finishes, you can still manipulate the innards of your class.
– dyslexicanaboko
Jul 22 '12 at 5:57
3
Actually i did the Same thing as u mentioned above but m facing this error java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
– Dhruv Tyagi
Aug 30 '16 at 11:08
44
This is exactly the wrong answer. I come across this all the time in peoples code, and its annoying to have to fix it all the time. AsyncTask should not be used for network activity, because it's tied to the activity, but not the activity lifecycle. Rotating the device with this task is running will cause an exception and crash your app. Use an IntentService that drops data in the sqlite database instead.
– Brill Pappin
Sep 9 '16 at 19:08
1
Caution, AsyncTask is often used for per activity network operations when it should not be. its lifecycle is not in sync with the activity. For fetching data, you should use an IntentService and the database behind the view.
– Brill Pappin
Oct 5 '16 at 21:24
1
@BrillPappin I am glad that i explored the comments, otherwise i would have gone with Async Task thanks.
– Shivam Pokhriyal
Sep 5 '18 at 5:26
|
show 11 more comments
This exception is thrown when an application attempts to perform a networking operation on its main thread. Run your code in AsyncTask
:
class RetrieveFeedTask extends AsyncTask<String, Void, RSSFeed> {
private Exception exception;
protected RSSFeed doInBackground(String... urls) {
try {
URL url = new URL(urls[0]);
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();
} catch (Exception e) {
this.exception = e;
return null;
} finally {
is.close();
}
}
protected void onPostExecute(RSSFeed feed) {
// TODO: check this.exception
// TODO: do something with the feed
}
}
How to execute the task:
In MainActivity.java
file you can add this line within your oncreate()
method
new RetrieveFeedTask().execute(urlToRssFeed);
Don't forget to add this to AndroidManifest.xml
file:
<uses-permission android:name="android.permission.INTERNET"/>
31
I think it is worth noting here that the code snippet above is supposed to be a subclass (inner class), preferably private. That way when the AsyncTask finishes, you can still manipulate the innards of your class.
– dyslexicanaboko
Jul 22 '12 at 5:57
3
Actually i did the Same thing as u mentioned above but m facing this error java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
– Dhruv Tyagi
Aug 30 '16 at 11:08
44
This is exactly the wrong answer. I come across this all the time in peoples code, and its annoying to have to fix it all the time. AsyncTask should not be used for network activity, because it's tied to the activity, but not the activity lifecycle. Rotating the device with this task is running will cause an exception and crash your app. Use an IntentService that drops data in the sqlite database instead.
– Brill Pappin
Sep 9 '16 at 19:08
1
Caution, AsyncTask is often used for per activity network operations when it should not be. its lifecycle is not in sync with the activity. For fetching data, you should use an IntentService and the database behind the view.
– Brill Pappin
Oct 5 '16 at 21:24
1
@BrillPappin I am glad that i explored the comments, otherwise i would have gone with Async Task thanks.
– Shivam Pokhriyal
Sep 5 '18 at 5:26
|
show 11 more comments
This exception is thrown when an application attempts to perform a networking operation on its main thread. Run your code in AsyncTask
:
class RetrieveFeedTask extends AsyncTask<String, Void, RSSFeed> {
private Exception exception;
protected RSSFeed doInBackground(String... urls) {
try {
URL url = new URL(urls[0]);
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();
} catch (Exception e) {
this.exception = e;
return null;
} finally {
is.close();
}
}
protected void onPostExecute(RSSFeed feed) {
// TODO: check this.exception
// TODO: do something with the feed
}
}
How to execute the task:
In MainActivity.java
file you can add this line within your oncreate()
method
new RetrieveFeedTask().execute(urlToRssFeed);
Don't forget to add this to AndroidManifest.xml
file:
<uses-permission android:name="android.permission.INTERNET"/>
This exception is thrown when an application attempts to perform a networking operation on its main thread. Run your code in AsyncTask
:
class RetrieveFeedTask extends AsyncTask<String, Void, RSSFeed> {
private Exception exception;
protected RSSFeed doInBackground(String... urls) {
try {
URL url = new URL(urls[0]);
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();
} catch (Exception e) {
this.exception = e;
return null;
} finally {
is.close();
}
}
protected void onPostExecute(RSSFeed feed) {
// TODO: check this.exception
// TODO: do something with the feed
}
}
How to execute the task:
In MainActivity.java
file you can add this line within your oncreate()
method
new RetrieveFeedTask().execute(urlToRssFeed);
Don't forget to add this to AndroidManifest.xml
file:
<uses-permission android:name="android.permission.INTERNET"/>
edited Nov 28 '17 at 11:57
Vova Stelmashchuk
322111
322111
answered Jun 14 '11 at 12:15
spektomspektom
28.9k24274
28.9k24274
31
I think it is worth noting here that the code snippet above is supposed to be a subclass (inner class), preferably private. That way when the AsyncTask finishes, you can still manipulate the innards of your class.
– dyslexicanaboko
Jul 22 '12 at 5:57
3
Actually i did the Same thing as u mentioned above but m facing this error java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
– Dhruv Tyagi
Aug 30 '16 at 11:08
44
This is exactly the wrong answer. I come across this all the time in peoples code, and its annoying to have to fix it all the time. AsyncTask should not be used for network activity, because it's tied to the activity, but not the activity lifecycle. Rotating the device with this task is running will cause an exception and crash your app. Use an IntentService that drops data in the sqlite database instead.
– Brill Pappin
Sep 9 '16 at 19:08
1
Caution, AsyncTask is often used for per activity network operations when it should not be. its lifecycle is not in sync with the activity. For fetching data, you should use an IntentService and the database behind the view.
– Brill Pappin
Oct 5 '16 at 21:24
1
@BrillPappin I am glad that i explored the comments, otherwise i would have gone with Async Task thanks.
– Shivam Pokhriyal
Sep 5 '18 at 5:26
|
show 11 more comments
31
I think it is worth noting here that the code snippet above is supposed to be a subclass (inner class), preferably private. That way when the AsyncTask finishes, you can still manipulate the innards of your class.
– dyslexicanaboko
Jul 22 '12 at 5:57
3
Actually i did the Same thing as u mentioned above but m facing this error java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
– Dhruv Tyagi
Aug 30 '16 at 11:08
44
This is exactly the wrong answer. I come across this all the time in peoples code, and its annoying to have to fix it all the time. AsyncTask should not be used for network activity, because it's tied to the activity, but not the activity lifecycle. Rotating the device with this task is running will cause an exception and crash your app. Use an IntentService that drops data in the sqlite database instead.
– Brill Pappin
Sep 9 '16 at 19:08
1
Caution, AsyncTask is often used for per activity network operations when it should not be. its lifecycle is not in sync with the activity. For fetching data, you should use an IntentService and the database behind the view.
– Brill Pappin
Oct 5 '16 at 21:24
1
@BrillPappin I am glad that i explored the comments, otherwise i would have gone with Async Task thanks.
– Shivam Pokhriyal
Sep 5 '18 at 5:26
31
31
I think it is worth noting here that the code snippet above is supposed to be a subclass (inner class), preferably private. That way when the AsyncTask finishes, you can still manipulate the innards of your class.
– dyslexicanaboko
Jul 22 '12 at 5:57
I think it is worth noting here that the code snippet above is supposed to be a subclass (inner class), preferably private. That way when the AsyncTask finishes, you can still manipulate the innards of your class.
– dyslexicanaboko
Jul 22 '12 at 5:57
3
3
Actually i did the Same thing as u mentioned above but m facing this error java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
– Dhruv Tyagi
Aug 30 '16 at 11:08
Actually i did the Same thing as u mentioned above but m facing this error java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
– Dhruv Tyagi
Aug 30 '16 at 11:08
44
44
This is exactly the wrong answer. I come across this all the time in peoples code, and its annoying to have to fix it all the time. AsyncTask should not be used for network activity, because it's tied to the activity, but not the activity lifecycle. Rotating the device with this task is running will cause an exception and crash your app. Use an IntentService that drops data in the sqlite database instead.
– Brill Pappin
Sep 9 '16 at 19:08
This is exactly the wrong answer. I come across this all the time in peoples code, and its annoying to have to fix it all the time. AsyncTask should not be used for network activity, because it's tied to the activity, but not the activity lifecycle. Rotating the device with this task is running will cause an exception and crash your app. Use an IntentService that drops data in the sqlite database instead.
– Brill Pappin
Sep 9 '16 at 19:08
1
1
Caution, AsyncTask is often used for per activity network operations when it should not be. its lifecycle is not in sync with the activity. For fetching data, you should use an IntentService and the database behind the view.
– Brill Pappin
Oct 5 '16 at 21:24
Caution, AsyncTask is often used for per activity network operations when it should not be. its lifecycle is not in sync with the activity. For fetching data, you should use an IntentService and the database behind the view.
– Brill Pappin
Oct 5 '16 at 21:24
1
1
@BrillPappin I am glad that i explored the comments, otherwise i would have gone with Async Task thanks.
– Shivam Pokhriyal
Sep 5 '18 at 5:26
@BrillPappin I am glad that i explored the comments, otherwise i would have gone with Async Task thanks.
– Shivam Pokhriyal
Sep 5 '18 at 5:26
|
show 11 more comments
You should almost always run network operations on a thread or as an asynchronous task.
But it is possible to remove this restriction and you override the default behavior, if you are willing to accept the consequences.
Add:
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
In your class,
and
ADD this permission in android manifest.xml file:
<uses-permission android:name="android.permission.INTERNET"/>
Consequences:
Your app will (in areas of spotty internet connection) become unresponsive and lock up, the user perceives slowness and has to do a force kill, and you risk the activity manager killing your app and telling the user that the app has stopped.
Android has some good tips on good programming practices to design for responsiveness:
http://developer.android.com/reference/android/os/NetworkOnMainThreadException.html
432
This is a very bad idea. the solution is to avoid network IO on main thread (as the accepted answer shows).
– MByD
May 14 '12 at 14:10
66
With this you only hide your real problem.
– Alex
Jun 18 '12 at 6:44
24
@TwistedUmbrella The AsyncTask does not add a page of code, it adds 6 lines (class declaration, override annotation,doInBackground
declaration, 2 closing brackets and a call toexecute()
). On the other hand, even a single fetch from a site as you mention brings a significant lag in the UI responsiveness. Don't be lazy.
– Zoltán
Sep 4 '12 at 9:39
50
@TwistedUmbrella Don't be silly. That is how bad applications are made. Whether it is downloading a text file or an image gallery, you should follow best practices. And running network IO on main thread is not a best practice.
– States
Nov 1 '12 at 1:23
79
Upvoted. This answer is correct, and for the many programmers who are neither naive nor stupid, but who simply require a SYNCHRONOUS (i.e.: this must block the app) call, this is exactly what's needed. I'm more than happy that Android throws the exception by default (IMHO it's a very "helpful" thing to do!) - but I'm equally happy to say "thanks, but - this is actually what I intended" and to override it.
– Adam
May 1 '13 at 6:48
|
show 42 more comments
You should almost always run network operations on a thread or as an asynchronous task.
But it is possible to remove this restriction and you override the default behavior, if you are willing to accept the consequences.
Add:
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
In your class,
and
ADD this permission in android manifest.xml file:
<uses-permission android:name="android.permission.INTERNET"/>
Consequences:
Your app will (in areas of spotty internet connection) become unresponsive and lock up, the user perceives slowness and has to do a force kill, and you risk the activity manager killing your app and telling the user that the app has stopped.
Android has some good tips on good programming practices to design for responsiveness:
http://developer.android.com/reference/android/os/NetworkOnMainThreadException.html
432
This is a very bad idea. the solution is to avoid network IO on main thread (as the accepted answer shows).
– MByD
May 14 '12 at 14:10
66
With this you only hide your real problem.
– Alex
Jun 18 '12 at 6:44
24
@TwistedUmbrella The AsyncTask does not add a page of code, it adds 6 lines (class declaration, override annotation,doInBackground
declaration, 2 closing brackets and a call toexecute()
). On the other hand, even a single fetch from a site as you mention brings a significant lag in the UI responsiveness. Don't be lazy.
– Zoltán
Sep 4 '12 at 9:39
50
@TwistedUmbrella Don't be silly. That is how bad applications are made. Whether it is downloading a text file or an image gallery, you should follow best practices. And running network IO on main thread is not a best practice.
– States
Nov 1 '12 at 1:23
79
Upvoted. This answer is correct, and for the many programmers who are neither naive nor stupid, but who simply require a SYNCHRONOUS (i.e.: this must block the app) call, this is exactly what's needed. I'm more than happy that Android throws the exception by default (IMHO it's a very "helpful" thing to do!) - but I'm equally happy to say "thanks, but - this is actually what I intended" and to override it.
– Adam
May 1 '13 at 6:48
|
show 42 more comments
You should almost always run network operations on a thread or as an asynchronous task.
But it is possible to remove this restriction and you override the default behavior, if you are willing to accept the consequences.
Add:
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
In your class,
and
ADD this permission in android manifest.xml file:
<uses-permission android:name="android.permission.INTERNET"/>
Consequences:
Your app will (in areas of spotty internet connection) become unresponsive and lock up, the user perceives slowness and has to do a force kill, and you risk the activity manager killing your app and telling the user that the app has stopped.
Android has some good tips on good programming practices to design for responsiveness:
http://developer.android.com/reference/android/os/NetworkOnMainThreadException.html
You should almost always run network operations on a thread or as an asynchronous task.
But it is possible to remove this restriction and you override the default behavior, if you are willing to accept the consequences.
Add:
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
In your class,
and
ADD this permission in android manifest.xml file:
<uses-permission android:name="android.permission.INTERNET"/>
Consequences:
Your app will (in areas of spotty internet connection) become unresponsive and lock up, the user perceives slowness and has to do a force kill, and you risk the activity manager killing your app and telling the user that the app has stopped.
Android has some good tips on good programming practices to design for responsiveness:
http://developer.android.com/reference/android/os/NetworkOnMainThreadException.html
edited Feb 11 '18 at 14:18


EpicPandaForce
48k14127252
48k14127252
answered Feb 15 '12 at 6:59
user1169115user1169115
7,159182
7,159182
432
This is a very bad idea. the solution is to avoid network IO on main thread (as the accepted answer shows).
– MByD
May 14 '12 at 14:10
66
With this you only hide your real problem.
– Alex
Jun 18 '12 at 6:44
24
@TwistedUmbrella The AsyncTask does not add a page of code, it adds 6 lines (class declaration, override annotation,doInBackground
declaration, 2 closing brackets and a call toexecute()
). On the other hand, even a single fetch from a site as you mention brings a significant lag in the UI responsiveness. Don't be lazy.
– Zoltán
Sep 4 '12 at 9:39
50
@TwistedUmbrella Don't be silly. That is how bad applications are made. Whether it is downloading a text file or an image gallery, you should follow best practices. And running network IO on main thread is not a best practice.
– States
Nov 1 '12 at 1:23
79
Upvoted. This answer is correct, and for the many programmers who are neither naive nor stupid, but who simply require a SYNCHRONOUS (i.e.: this must block the app) call, this is exactly what's needed. I'm more than happy that Android throws the exception by default (IMHO it's a very "helpful" thing to do!) - but I'm equally happy to say "thanks, but - this is actually what I intended" and to override it.
– Adam
May 1 '13 at 6:48
|
show 42 more comments
432
This is a very bad idea. the solution is to avoid network IO on main thread (as the accepted answer shows).
– MByD
May 14 '12 at 14:10
66
With this you only hide your real problem.
– Alex
Jun 18 '12 at 6:44
24
@TwistedUmbrella The AsyncTask does not add a page of code, it adds 6 lines (class declaration, override annotation,doInBackground
declaration, 2 closing brackets and a call toexecute()
). On the other hand, even a single fetch from a site as you mention brings a significant lag in the UI responsiveness. Don't be lazy.
– Zoltán
Sep 4 '12 at 9:39
50
@TwistedUmbrella Don't be silly. That is how bad applications are made. Whether it is downloading a text file or an image gallery, you should follow best practices. And running network IO on main thread is not a best practice.
– States
Nov 1 '12 at 1:23
79
Upvoted. This answer is correct, and for the many programmers who are neither naive nor stupid, but who simply require a SYNCHRONOUS (i.e.: this must block the app) call, this is exactly what's needed. I'm more than happy that Android throws the exception by default (IMHO it's a very "helpful" thing to do!) - but I'm equally happy to say "thanks, but - this is actually what I intended" and to override it.
– Adam
May 1 '13 at 6:48
432
432
This is a very bad idea. the solution is to avoid network IO on main thread (as the accepted answer shows).
– MByD
May 14 '12 at 14:10
This is a very bad idea. the solution is to avoid network IO on main thread (as the accepted answer shows).
– MByD
May 14 '12 at 14:10
66
66
With this you only hide your real problem.
– Alex
Jun 18 '12 at 6:44
With this you only hide your real problem.
– Alex
Jun 18 '12 at 6:44
24
24
@TwistedUmbrella The AsyncTask does not add a page of code, it adds 6 lines (class declaration, override annotation,
doInBackground
declaration, 2 closing brackets and a call to execute()
). On the other hand, even a single fetch from a site as you mention brings a significant lag in the UI responsiveness. Don't be lazy.– Zoltán
Sep 4 '12 at 9:39
@TwistedUmbrella The AsyncTask does not add a page of code, it adds 6 lines (class declaration, override annotation,
doInBackground
declaration, 2 closing brackets and a call to execute()
). On the other hand, even a single fetch from a site as you mention brings a significant lag in the UI responsiveness. Don't be lazy.– Zoltán
Sep 4 '12 at 9:39
50
50
@TwistedUmbrella Don't be silly. That is how bad applications are made. Whether it is downloading a text file or an image gallery, you should follow best practices. And running network IO on main thread is not a best practice.
– States
Nov 1 '12 at 1:23
@TwistedUmbrella Don't be silly. That is how bad applications are made. Whether it is downloading a text file or an image gallery, you should follow best practices. And running network IO on main thread is not a best practice.
– States
Nov 1 '12 at 1:23
79
79
Upvoted. This answer is correct, and for the many programmers who are neither naive nor stupid, but who simply require a SYNCHRONOUS (i.e.: this must block the app) call, this is exactly what's needed. I'm more than happy that Android throws the exception by default (IMHO it's a very "helpful" thing to do!) - but I'm equally happy to say "thanks, but - this is actually what I intended" and to override it.
– Adam
May 1 '13 at 6:48
Upvoted. This answer is correct, and for the many programmers who are neither naive nor stupid, but who simply require a SYNCHRONOUS (i.e.: this must block the app) call, this is exactly what's needed. I'm more than happy that Android throws the exception by default (IMHO it's a very "helpful" thing to do!) - but I'm equally happy to say "thanks, but - this is actually what I intended" and to override it.
– Adam
May 1 '13 at 6:48
|
show 42 more comments
I solved this problem using a new Thread
.
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
try {
//Your code goes here
} catch (Exception e) {
e.printStackTrace();
}
}
});
thread.start();
6
Instead of creating a new thread each time you want to perform a network operation, you could use a single thread executor service too.
– Alex Lockwood
Jan 27 '13 at 18:06
56
Simple but dangerous. The anonymous Runnable has an implicit reference to the enclosing class (e.g. your Activity or Fragment), preventing it from being garbage collected until the thread completes. You should at least set the priority to Process.BACKGROUND, else this thread will run at the same priority as the main/ui thread, contending with lifecycle methods and ui frame rates (watch out for warnings in log from the choreographer).
– Stevie
Jun 19 '14 at 12:39
@Stevie how to set the priority? neither runnble nor the executorService have such a setter method
– J. K.
May 31 '15 at 13:26
1
@J.K. Supply your ExecutorService with a custom ThreadFactory and call Thread.setPriority on the thread before returning it.
– Stevie
Jun 1 '15 at 19:14
Setting priority for something that is intended to do a network call (which will block) seems overkill.
– john16384
Jan 27 '16 at 13:09
|
show 2 more comments
I solved this problem using a new Thread
.
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
try {
//Your code goes here
} catch (Exception e) {
e.printStackTrace();
}
}
});
thread.start();
6
Instead of creating a new thread each time you want to perform a network operation, you could use a single thread executor service too.
– Alex Lockwood
Jan 27 '13 at 18:06
56
Simple but dangerous. The anonymous Runnable has an implicit reference to the enclosing class (e.g. your Activity or Fragment), preventing it from being garbage collected until the thread completes. You should at least set the priority to Process.BACKGROUND, else this thread will run at the same priority as the main/ui thread, contending with lifecycle methods and ui frame rates (watch out for warnings in log from the choreographer).
– Stevie
Jun 19 '14 at 12:39
@Stevie how to set the priority? neither runnble nor the executorService have such a setter method
– J. K.
May 31 '15 at 13:26
1
@J.K. Supply your ExecutorService with a custom ThreadFactory and call Thread.setPriority on the thread before returning it.
– Stevie
Jun 1 '15 at 19:14
Setting priority for something that is intended to do a network call (which will block) seems overkill.
– john16384
Jan 27 '16 at 13:09
|
show 2 more comments
I solved this problem using a new Thread
.
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
try {
//Your code goes here
} catch (Exception e) {
e.printStackTrace();
}
}
});
thread.start();
I solved this problem using a new Thread
.
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
try {
//Your code goes here
} catch (Exception e) {
e.printStackTrace();
}
}
});
thread.start();
edited Oct 5 '16 at 9:42


V-rund Puro-hit
3,96082044
3,96082044
answered Jan 21 '13 at 16:31


Dr.LuijiDr.Luiji
4,64511111
4,64511111
6
Instead of creating a new thread each time you want to perform a network operation, you could use a single thread executor service too.
– Alex Lockwood
Jan 27 '13 at 18:06
56
Simple but dangerous. The anonymous Runnable has an implicit reference to the enclosing class (e.g. your Activity or Fragment), preventing it from being garbage collected until the thread completes. You should at least set the priority to Process.BACKGROUND, else this thread will run at the same priority as the main/ui thread, contending with lifecycle methods and ui frame rates (watch out for warnings in log from the choreographer).
– Stevie
Jun 19 '14 at 12:39
@Stevie how to set the priority? neither runnble nor the executorService have such a setter method
– J. K.
May 31 '15 at 13:26
1
@J.K. Supply your ExecutorService with a custom ThreadFactory and call Thread.setPriority on the thread before returning it.
– Stevie
Jun 1 '15 at 19:14
Setting priority for something that is intended to do a network call (which will block) seems overkill.
– john16384
Jan 27 '16 at 13:09
|
show 2 more comments
6
Instead of creating a new thread each time you want to perform a network operation, you could use a single thread executor service too.
– Alex Lockwood
Jan 27 '13 at 18:06
56
Simple but dangerous. The anonymous Runnable has an implicit reference to the enclosing class (e.g. your Activity or Fragment), preventing it from being garbage collected until the thread completes. You should at least set the priority to Process.BACKGROUND, else this thread will run at the same priority as the main/ui thread, contending with lifecycle methods and ui frame rates (watch out for warnings in log from the choreographer).
– Stevie
Jun 19 '14 at 12:39
@Stevie how to set the priority? neither runnble nor the executorService have such a setter method
– J. K.
May 31 '15 at 13:26
1
@J.K. Supply your ExecutorService with a custom ThreadFactory and call Thread.setPriority on the thread before returning it.
– Stevie
Jun 1 '15 at 19:14
Setting priority for something that is intended to do a network call (which will block) seems overkill.
– john16384
Jan 27 '16 at 13:09
6
6
Instead of creating a new thread each time you want to perform a network operation, you could use a single thread executor service too.
– Alex Lockwood
Jan 27 '13 at 18:06
Instead of creating a new thread each time you want to perform a network operation, you could use a single thread executor service too.
– Alex Lockwood
Jan 27 '13 at 18:06
56
56
Simple but dangerous. The anonymous Runnable has an implicit reference to the enclosing class (e.g. your Activity or Fragment), preventing it from being garbage collected until the thread completes. You should at least set the priority to Process.BACKGROUND, else this thread will run at the same priority as the main/ui thread, contending with lifecycle methods and ui frame rates (watch out for warnings in log from the choreographer).
– Stevie
Jun 19 '14 at 12:39
Simple but dangerous. The anonymous Runnable has an implicit reference to the enclosing class (e.g. your Activity or Fragment), preventing it from being garbage collected until the thread completes. You should at least set the priority to Process.BACKGROUND, else this thread will run at the same priority as the main/ui thread, contending with lifecycle methods and ui frame rates (watch out for warnings in log from the choreographer).
– Stevie
Jun 19 '14 at 12:39
@Stevie how to set the priority? neither runnble nor the executorService have such a setter method
– J. K.
May 31 '15 at 13:26
@Stevie how to set the priority? neither runnble nor the executorService have such a setter method
– J. K.
May 31 '15 at 13:26
1
1
@J.K. Supply your ExecutorService with a custom ThreadFactory and call Thread.setPriority on the thread before returning it.
– Stevie
Jun 1 '15 at 19:14
@J.K. Supply your ExecutorService with a custom ThreadFactory and call Thread.setPriority on the thread before returning it.
– Stevie
Jun 1 '15 at 19:14
Setting priority for something that is intended to do a network call (which will block) seems overkill.
– john16384
Jan 27 '16 at 13:09
Setting priority for something that is intended to do a network call (which will block) seems overkill.
– john16384
Jan 27 '16 at 13:09
|
show 2 more comments
You cannot perform network I/O on the UI thread on Honeycomb. Technically, it is possible on earlier versions of Android, but it is a really bad idea as it will cause your app to stop responding, and can result in the OS killing your app for being badly behaved. You'll need to run a background process or use AsyncTask to perform your network transaction on a background thread.
There is an article about Painless Threading on the Android developer site which is a good introduction to this, and it will provide you with a much better depth of an answer than can be realistically provided here.
add a comment |
You cannot perform network I/O on the UI thread on Honeycomb. Technically, it is possible on earlier versions of Android, but it is a really bad idea as it will cause your app to stop responding, and can result in the OS killing your app for being badly behaved. You'll need to run a background process or use AsyncTask to perform your network transaction on a background thread.
There is an article about Painless Threading on the Android developer site which is a good introduction to this, and it will provide you with a much better depth of an answer than can be realistically provided here.
add a comment |
You cannot perform network I/O on the UI thread on Honeycomb. Technically, it is possible on earlier versions of Android, but it is a really bad idea as it will cause your app to stop responding, and can result in the OS killing your app for being badly behaved. You'll need to run a background process or use AsyncTask to perform your network transaction on a background thread.
There is an article about Painless Threading on the Android developer site which is a good introduction to this, and it will provide you with a much better depth of an answer than can be realistically provided here.
You cannot perform network I/O on the UI thread on Honeycomb. Technically, it is possible on earlier versions of Android, but it is a really bad idea as it will cause your app to stop responding, and can result in the OS killing your app for being badly behaved. You'll need to run a background process or use AsyncTask to perform your network transaction on a background thread.
There is an article about Painless Threading on the Android developer site which is a good introduction to this, and it will provide you with a much better depth of an answer than can be realistically provided here.
edited Feb 9 '14 at 16:25


Peter Mortensen
13.5k1984111
13.5k1984111
answered Jun 14 '11 at 12:07


Mark AllisonMark Allison
19.9k83945
19.9k83945
add a comment |
add a comment |
The accepted answer has some significant down-sides. It is not advisable to use AsyncTask for networking unless you really know what you are doing. Some of the down-sides include:
- AsyncTask's created as non-static inner classes have an implicit reference to the enclosing Activity object, its context, and the entire View hierarchy created by that activity. This reference prevents the Activity from being garbage collected until the AsyncTask's background work completes. If the user's connection is slow, and/or the download is large, these short-term memory leaks can become a problem - for example if the orientation changes several times (and you don't cancel the executing tasks), or the user navigates away from the Activity.
- AsyncTask has different execution characteristics depending on the platform it executes on: prior to API level 4 AsyncTasks execute serially on a single background thread; from API level 4 through API level 10, AsyncTasks execute on a pool of up to 128 threads; from API level 11 onwards AsyncTask executes serially on a single background thread (unless you use the overloaded
executeOnExecutor
method and supply an alternative executor). Code that works fine when run serially on ICS may break when executed concurrently on Gingerbread, say, if you have inadvertent order-of-execution dependencies.
If you want to avoid short-term memory leaks, have well defined execution characteristics across all platforms, and have a base to build really robust network handling, you might want to consider:
- Using a library that does a nice job of this for you - there's a nice comparison of networking libs in this question, or
- Using a
Service
orIntentService
instead, perhaps with aPendingIntent
to return the result via the Activity'sonActivityResult
method.
IntentService approach
Down-sides:
- More code and complexity than
AsyncTask
, though not as much as you might think - Will queue requests and run them on a single background thread. You can easily control this by replacing
IntentService
with an equivalentService
implementation, perhaps like this one. - Um, I can't think of any others right now actually
Up-sides:
- Avoids the short-term memory leak problem
- If your activity restarts while network operations are in-flight it can still receive the result of the download via its
onActivityResult
method - Better platform than AsyncTask to build and re-use robust networking code. Example: if you need to do an important upload, you could do it from
AsyncTask
in anActivity
, but if the user context-switches out of the app to take a phone-call, the system may kill the app before the upload completes. It is less likely to kill an application with an activeService
. - If you use your own concurrent version of
IntentService
(like the one I linked above) you can control the level of concurrency via theExecutor
.
Implementation summary
You can implement an IntentService
to perform downloads on a single background thread quite easily.
Step 1: Create an IntentService
to perform the download. You can tell it what to download via Intent
extra's, and pass it a PendingIntent
to use to return the result to the Activity
:
import android.app.IntentService;
import android.app.PendingIntent;
import android.content.Intent;
import android.util.Log;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
public class DownloadIntentService extends IntentService {
private static final String TAG = DownloadIntentService.class.getSimpleName();
public static final String PENDING_RESULT_EXTRA = "pending_result";
public static final String URL_EXTRA = "url";
public static final String RSS_RESULT_EXTRA = "url";
public static final int RESULT_CODE = 0;
public static final int INVALID_URL_CODE = 1;
public static final int ERROR_CODE = 2;
private IllustrativeRSSParser parser;
public DownloadIntentService() {
super(TAG);
// make one and re-use, in the case where more than one intent is queued
parser = new IllustrativeRSSParser();
}
@Override
protected void onHandleIntent(Intent intent) {
PendingIntent reply = intent.getParcelableExtra(PENDING_RESULT_EXTRA);
InputStream in = null;
try {
try {
URL url = new URL(intent.getStringExtra(URL_EXTRA));
IllustrativeRSS rss = parser.parse(in = url.openStream());
Intent result = new Intent();
result.putExtra(RSS_RESULT_EXTRA, rss);
reply.send(this, RESULT_CODE, result);
} catch (MalformedURLException exc) {
reply.send(INVALID_URL_CODE);
} catch (Exception exc) {
// could do better by treating the different sax/xml exceptions individually
reply.send(ERROR_CODE);
}
} catch (PendingIntent.CanceledException exc) {
Log.i(TAG, "reply cancelled", exc);
}
}
}
Step 2: Register the service in the manifest:
<service
android:name=".DownloadIntentService"
android:exported="false"/>
Step 3: Invoke the service from the Activity, passing a PendingResult object which the Service will use to return the result:
PendingIntent pendingResult = createPendingResult(
RSS_DOWNLOAD_REQUEST_CODE, new Intent(), 0);
Intent intent = new Intent(getApplicationContext(), DownloadIntentService.class);
intent.putExtra(DownloadIntentService.URL_EXTRA, URL);
intent.putExtra(DownloadIntentService.PENDING_RESULT_EXTRA, pendingResult);
startService(intent);
Step 4: Handle the result in onActivityResult:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == RSS_DOWNLOAD_REQUEST_CODE) {
switch (resultCode) {
case DownloadIntentService.INVALID_URL_CODE:
handleInvalidURL();
break;
case DownloadIntentService.ERROR_CODE:
handleError(data);
break;
case DownloadIntentService.RESULT_CODE:
handleRSS(data);
break;
}
handleRSS(data);
}
super.onActivityResult(requestCode, resultCode, data);
}
A github project containing a complete working Android-Studio/gradle project is available here.
IntentService is the correct way to do this, not uprooting because AsyncTask is exactly the way not to do it.
– Brill Pappin
Sep 10 '16 at 14:59
2
@BrillPappin I almost entirely agree and have re-worded to emphasize the drawbacks of AsyncTask. (I still think there are a very small number of cases where - if you really know what you are doing - it might be OK to use AsyncTask, but the accepted answer doesn't point out any drawbacks and is way too popular for the good of Android).
– Stevie
Mar 13 '17 at 12:56
Do you actually needIllustrativeRSS
? What if you're not working with RSS stuff?
– Cullub
Apr 14 '18 at 19:13
add a comment |
The accepted answer has some significant down-sides. It is not advisable to use AsyncTask for networking unless you really know what you are doing. Some of the down-sides include:
- AsyncTask's created as non-static inner classes have an implicit reference to the enclosing Activity object, its context, and the entire View hierarchy created by that activity. This reference prevents the Activity from being garbage collected until the AsyncTask's background work completes. If the user's connection is slow, and/or the download is large, these short-term memory leaks can become a problem - for example if the orientation changes several times (and you don't cancel the executing tasks), or the user navigates away from the Activity.
- AsyncTask has different execution characteristics depending on the platform it executes on: prior to API level 4 AsyncTasks execute serially on a single background thread; from API level 4 through API level 10, AsyncTasks execute on a pool of up to 128 threads; from API level 11 onwards AsyncTask executes serially on a single background thread (unless you use the overloaded
executeOnExecutor
method and supply an alternative executor). Code that works fine when run serially on ICS may break when executed concurrently on Gingerbread, say, if you have inadvertent order-of-execution dependencies.
If you want to avoid short-term memory leaks, have well defined execution characteristics across all platforms, and have a base to build really robust network handling, you might want to consider:
- Using a library that does a nice job of this for you - there's a nice comparison of networking libs in this question, or
- Using a
Service
orIntentService
instead, perhaps with aPendingIntent
to return the result via the Activity'sonActivityResult
method.
IntentService approach
Down-sides:
- More code and complexity than
AsyncTask
, though not as much as you might think - Will queue requests and run them on a single background thread. You can easily control this by replacing
IntentService
with an equivalentService
implementation, perhaps like this one. - Um, I can't think of any others right now actually
Up-sides:
- Avoids the short-term memory leak problem
- If your activity restarts while network operations are in-flight it can still receive the result of the download via its
onActivityResult
method - Better platform than AsyncTask to build and re-use robust networking code. Example: if you need to do an important upload, you could do it from
AsyncTask
in anActivity
, but if the user context-switches out of the app to take a phone-call, the system may kill the app before the upload completes. It is less likely to kill an application with an activeService
. - If you use your own concurrent version of
IntentService
(like the one I linked above) you can control the level of concurrency via theExecutor
.
Implementation summary
You can implement an IntentService
to perform downloads on a single background thread quite easily.
Step 1: Create an IntentService
to perform the download. You can tell it what to download via Intent
extra's, and pass it a PendingIntent
to use to return the result to the Activity
:
import android.app.IntentService;
import android.app.PendingIntent;
import android.content.Intent;
import android.util.Log;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
public class DownloadIntentService extends IntentService {
private static final String TAG = DownloadIntentService.class.getSimpleName();
public static final String PENDING_RESULT_EXTRA = "pending_result";
public static final String URL_EXTRA = "url";
public static final String RSS_RESULT_EXTRA = "url";
public static final int RESULT_CODE = 0;
public static final int INVALID_URL_CODE = 1;
public static final int ERROR_CODE = 2;
private IllustrativeRSSParser parser;
public DownloadIntentService() {
super(TAG);
// make one and re-use, in the case where more than one intent is queued
parser = new IllustrativeRSSParser();
}
@Override
protected void onHandleIntent(Intent intent) {
PendingIntent reply = intent.getParcelableExtra(PENDING_RESULT_EXTRA);
InputStream in = null;
try {
try {
URL url = new URL(intent.getStringExtra(URL_EXTRA));
IllustrativeRSS rss = parser.parse(in = url.openStream());
Intent result = new Intent();
result.putExtra(RSS_RESULT_EXTRA, rss);
reply.send(this, RESULT_CODE, result);
} catch (MalformedURLException exc) {
reply.send(INVALID_URL_CODE);
} catch (Exception exc) {
// could do better by treating the different sax/xml exceptions individually
reply.send(ERROR_CODE);
}
} catch (PendingIntent.CanceledException exc) {
Log.i(TAG, "reply cancelled", exc);
}
}
}
Step 2: Register the service in the manifest:
<service
android:name=".DownloadIntentService"
android:exported="false"/>
Step 3: Invoke the service from the Activity, passing a PendingResult object which the Service will use to return the result:
PendingIntent pendingResult = createPendingResult(
RSS_DOWNLOAD_REQUEST_CODE, new Intent(), 0);
Intent intent = new Intent(getApplicationContext(), DownloadIntentService.class);
intent.putExtra(DownloadIntentService.URL_EXTRA, URL);
intent.putExtra(DownloadIntentService.PENDING_RESULT_EXTRA, pendingResult);
startService(intent);
Step 4: Handle the result in onActivityResult:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == RSS_DOWNLOAD_REQUEST_CODE) {
switch (resultCode) {
case DownloadIntentService.INVALID_URL_CODE:
handleInvalidURL();
break;
case DownloadIntentService.ERROR_CODE:
handleError(data);
break;
case DownloadIntentService.RESULT_CODE:
handleRSS(data);
break;
}
handleRSS(data);
}
super.onActivityResult(requestCode, resultCode, data);
}
A github project containing a complete working Android-Studio/gradle project is available here.
IntentService is the correct way to do this, not uprooting because AsyncTask is exactly the way not to do it.
– Brill Pappin
Sep 10 '16 at 14:59
2
@BrillPappin I almost entirely agree and have re-worded to emphasize the drawbacks of AsyncTask. (I still think there are a very small number of cases where - if you really know what you are doing - it might be OK to use AsyncTask, but the accepted answer doesn't point out any drawbacks and is way too popular for the good of Android).
– Stevie
Mar 13 '17 at 12:56
Do you actually needIllustrativeRSS
? What if you're not working with RSS stuff?
– Cullub
Apr 14 '18 at 19:13
add a comment |
The accepted answer has some significant down-sides. It is not advisable to use AsyncTask for networking unless you really know what you are doing. Some of the down-sides include:
- AsyncTask's created as non-static inner classes have an implicit reference to the enclosing Activity object, its context, and the entire View hierarchy created by that activity. This reference prevents the Activity from being garbage collected until the AsyncTask's background work completes. If the user's connection is slow, and/or the download is large, these short-term memory leaks can become a problem - for example if the orientation changes several times (and you don't cancel the executing tasks), or the user navigates away from the Activity.
- AsyncTask has different execution characteristics depending on the platform it executes on: prior to API level 4 AsyncTasks execute serially on a single background thread; from API level 4 through API level 10, AsyncTasks execute on a pool of up to 128 threads; from API level 11 onwards AsyncTask executes serially on a single background thread (unless you use the overloaded
executeOnExecutor
method and supply an alternative executor). Code that works fine when run serially on ICS may break when executed concurrently on Gingerbread, say, if you have inadvertent order-of-execution dependencies.
If you want to avoid short-term memory leaks, have well defined execution characteristics across all platforms, and have a base to build really robust network handling, you might want to consider:
- Using a library that does a nice job of this for you - there's a nice comparison of networking libs in this question, or
- Using a
Service
orIntentService
instead, perhaps with aPendingIntent
to return the result via the Activity'sonActivityResult
method.
IntentService approach
Down-sides:
- More code and complexity than
AsyncTask
, though not as much as you might think - Will queue requests and run them on a single background thread. You can easily control this by replacing
IntentService
with an equivalentService
implementation, perhaps like this one. - Um, I can't think of any others right now actually
Up-sides:
- Avoids the short-term memory leak problem
- If your activity restarts while network operations are in-flight it can still receive the result of the download via its
onActivityResult
method - Better platform than AsyncTask to build and re-use robust networking code. Example: if you need to do an important upload, you could do it from
AsyncTask
in anActivity
, but if the user context-switches out of the app to take a phone-call, the system may kill the app before the upload completes. It is less likely to kill an application with an activeService
. - If you use your own concurrent version of
IntentService
(like the one I linked above) you can control the level of concurrency via theExecutor
.
Implementation summary
You can implement an IntentService
to perform downloads on a single background thread quite easily.
Step 1: Create an IntentService
to perform the download. You can tell it what to download via Intent
extra's, and pass it a PendingIntent
to use to return the result to the Activity
:
import android.app.IntentService;
import android.app.PendingIntent;
import android.content.Intent;
import android.util.Log;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
public class DownloadIntentService extends IntentService {
private static final String TAG = DownloadIntentService.class.getSimpleName();
public static final String PENDING_RESULT_EXTRA = "pending_result";
public static final String URL_EXTRA = "url";
public static final String RSS_RESULT_EXTRA = "url";
public static final int RESULT_CODE = 0;
public static final int INVALID_URL_CODE = 1;
public static final int ERROR_CODE = 2;
private IllustrativeRSSParser parser;
public DownloadIntentService() {
super(TAG);
// make one and re-use, in the case where more than one intent is queued
parser = new IllustrativeRSSParser();
}
@Override
protected void onHandleIntent(Intent intent) {
PendingIntent reply = intent.getParcelableExtra(PENDING_RESULT_EXTRA);
InputStream in = null;
try {
try {
URL url = new URL(intent.getStringExtra(URL_EXTRA));
IllustrativeRSS rss = parser.parse(in = url.openStream());
Intent result = new Intent();
result.putExtra(RSS_RESULT_EXTRA, rss);
reply.send(this, RESULT_CODE, result);
} catch (MalformedURLException exc) {
reply.send(INVALID_URL_CODE);
} catch (Exception exc) {
// could do better by treating the different sax/xml exceptions individually
reply.send(ERROR_CODE);
}
} catch (PendingIntent.CanceledException exc) {
Log.i(TAG, "reply cancelled", exc);
}
}
}
Step 2: Register the service in the manifest:
<service
android:name=".DownloadIntentService"
android:exported="false"/>
Step 3: Invoke the service from the Activity, passing a PendingResult object which the Service will use to return the result:
PendingIntent pendingResult = createPendingResult(
RSS_DOWNLOAD_REQUEST_CODE, new Intent(), 0);
Intent intent = new Intent(getApplicationContext(), DownloadIntentService.class);
intent.putExtra(DownloadIntentService.URL_EXTRA, URL);
intent.putExtra(DownloadIntentService.PENDING_RESULT_EXTRA, pendingResult);
startService(intent);
Step 4: Handle the result in onActivityResult:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == RSS_DOWNLOAD_REQUEST_CODE) {
switch (resultCode) {
case DownloadIntentService.INVALID_URL_CODE:
handleInvalidURL();
break;
case DownloadIntentService.ERROR_CODE:
handleError(data);
break;
case DownloadIntentService.RESULT_CODE:
handleRSS(data);
break;
}
handleRSS(data);
}
super.onActivityResult(requestCode, resultCode, data);
}
A github project containing a complete working Android-Studio/gradle project is available here.
The accepted answer has some significant down-sides. It is not advisable to use AsyncTask for networking unless you really know what you are doing. Some of the down-sides include:
- AsyncTask's created as non-static inner classes have an implicit reference to the enclosing Activity object, its context, and the entire View hierarchy created by that activity. This reference prevents the Activity from being garbage collected until the AsyncTask's background work completes. If the user's connection is slow, and/or the download is large, these short-term memory leaks can become a problem - for example if the orientation changes several times (and you don't cancel the executing tasks), or the user navigates away from the Activity.
- AsyncTask has different execution characteristics depending on the platform it executes on: prior to API level 4 AsyncTasks execute serially on a single background thread; from API level 4 through API level 10, AsyncTasks execute on a pool of up to 128 threads; from API level 11 onwards AsyncTask executes serially on a single background thread (unless you use the overloaded
executeOnExecutor
method and supply an alternative executor). Code that works fine when run serially on ICS may break when executed concurrently on Gingerbread, say, if you have inadvertent order-of-execution dependencies.
If you want to avoid short-term memory leaks, have well defined execution characteristics across all platforms, and have a base to build really robust network handling, you might want to consider:
- Using a library that does a nice job of this for you - there's a nice comparison of networking libs in this question, or
- Using a
Service
orIntentService
instead, perhaps with aPendingIntent
to return the result via the Activity'sonActivityResult
method.
IntentService approach
Down-sides:
- More code and complexity than
AsyncTask
, though not as much as you might think - Will queue requests and run them on a single background thread. You can easily control this by replacing
IntentService
with an equivalentService
implementation, perhaps like this one. - Um, I can't think of any others right now actually
Up-sides:
- Avoids the short-term memory leak problem
- If your activity restarts while network operations are in-flight it can still receive the result of the download via its
onActivityResult
method - Better platform than AsyncTask to build and re-use robust networking code. Example: if you need to do an important upload, you could do it from
AsyncTask
in anActivity
, but if the user context-switches out of the app to take a phone-call, the system may kill the app before the upload completes. It is less likely to kill an application with an activeService
. - If you use your own concurrent version of
IntentService
(like the one I linked above) you can control the level of concurrency via theExecutor
.
Implementation summary
You can implement an IntentService
to perform downloads on a single background thread quite easily.
Step 1: Create an IntentService
to perform the download. You can tell it what to download via Intent
extra's, and pass it a PendingIntent
to use to return the result to the Activity
:
import android.app.IntentService;
import android.app.PendingIntent;
import android.content.Intent;
import android.util.Log;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
public class DownloadIntentService extends IntentService {
private static final String TAG = DownloadIntentService.class.getSimpleName();
public static final String PENDING_RESULT_EXTRA = "pending_result";
public static final String URL_EXTRA = "url";
public static final String RSS_RESULT_EXTRA = "url";
public static final int RESULT_CODE = 0;
public static final int INVALID_URL_CODE = 1;
public static final int ERROR_CODE = 2;
private IllustrativeRSSParser parser;
public DownloadIntentService() {
super(TAG);
// make one and re-use, in the case where more than one intent is queued
parser = new IllustrativeRSSParser();
}
@Override
protected void onHandleIntent(Intent intent) {
PendingIntent reply = intent.getParcelableExtra(PENDING_RESULT_EXTRA);
InputStream in = null;
try {
try {
URL url = new URL(intent.getStringExtra(URL_EXTRA));
IllustrativeRSS rss = parser.parse(in = url.openStream());
Intent result = new Intent();
result.putExtra(RSS_RESULT_EXTRA, rss);
reply.send(this, RESULT_CODE, result);
} catch (MalformedURLException exc) {
reply.send(INVALID_URL_CODE);
} catch (Exception exc) {
// could do better by treating the different sax/xml exceptions individually
reply.send(ERROR_CODE);
}
} catch (PendingIntent.CanceledException exc) {
Log.i(TAG, "reply cancelled", exc);
}
}
}
Step 2: Register the service in the manifest:
<service
android:name=".DownloadIntentService"
android:exported="false"/>
Step 3: Invoke the service from the Activity, passing a PendingResult object which the Service will use to return the result:
PendingIntent pendingResult = createPendingResult(
RSS_DOWNLOAD_REQUEST_CODE, new Intent(), 0);
Intent intent = new Intent(getApplicationContext(), DownloadIntentService.class);
intent.putExtra(DownloadIntentService.URL_EXTRA, URL);
intent.putExtra(DownloadIntentService.PENDING_RESULT_EXTRA, pendingResult);
startService(intent);
Step 4: Handle the result in onActivityResult:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == RSS_DOWNLOAD_REQUEST_CODE) {
switch (resultCode) {
case DownloadIntentService.INVALID_URL_CODE:
handleInvalidURL();
break;
case DownloadIntentService.ERROR_CODE:
handleError(data);
break;
case DownloadIntentService.RESULT_CODE:
handleRSS(data);
break;
}
handleRSS(data);
}
super.onActivityResult(requestCode, resultCode, data);
}
A github project containing a complete working Android-Studio/gradle project is available here.
edited May 23 '17 at 12:34
Community♦
11
11
answered Jan 22 '14 at 13:17
StevieStevie
5,66132427
5,66132427
IntentService is the correct way to do this, not uprooting because AsyncTask is exactly the way not to do it.
– Brill Pappin
Sep 10 '16 at 14:59
2
@BrillPappin I almost entirely agree and have re-worded to emphasize the drawbacks of AsyncTask. (I still think there are a very small number of cases where - if you really know what you are doing - it might be OK to use AsyncTask, but the accepted answer doesn't point out any drawbacks and is way too popular for the good of Android).
– Stevie
Mar 13 '17 at 12:56
Do you actually needIllustrativeRSS
? What if you're not working with RSS stuff?
– Cullub
Apr 14 '18 at 19:13
add a comment |
IntentService is the correct way to do this, not uprooting because AsyncTask is exactly the way not to do it.
– Brill Pappin
Sep 10 '16 at 14:59
2
@BrillPappin I almost entirely agree and have re-worded to emphasize the drawbacks of AsyncTask. (I still think there are a very small number of cases where - if you really know what you are doing - it might be OK to use AsyncTask, but the accepted answer doesn't point out any drawbacks and is way too popular for the good of Android).
– Stevie
Mar 13 '17 at 12:56
Do you actually needIllustrativeRSS
? What if you're not working with RSS stuff?
– Cullub
Apr 14 '18 at 19:13
IntentService is the correct way to do this, not uprooting because AsyncTask is exactly the way not to do it.
– Brill Pappin
Sep 10 '16 at 14:59
IntentService is the correct way to do this, not uprooting because AsyncTask is exactly the way not to do it.
– Brill Pappin
Sep 10 '16 at 14:59
2
2
@BrillPappin I almost entirely agree and have re-worded to emphasize the drawbacks of AsyncTask. (I still think there are a very small number of cases where - if you really know what you are doing - it might be OK to use AsyncTask, but the accepted answer doesn't point out any drawbacks and is way too popular for the good of Android).
– Stevie
Mar 13 '17 at 12:56
@BrillPappin I almost entirely agree and have re-worded to emphasize the drawbacks of AsyncTask. (I still think there are a very small number of cases where - if you really know what you are doing - it might be OK to use AsyncTask, but the accepted answer doesn't point out any drawbacks and is way too popular for the good of Android).
– Stevie
Mar 13 '17 at 12:56
Do you actually need
IllustrativeRSS
? What if you're not working with RSS stuff?– Cullub
Apr 14 '18 at 19:13
Do you actually need
IllustrativeRSS
? What if you're not working with RSS stuff?– Cullub
Apr 14 '18 at 19:13
add a comment |
- Do not use strictMode (only in debug mode)
- Do not change SDK version
- Do not use a separate thread
Use Service or AsyncTask
See also Stack Overflow question:
android.os.NetworkOnMainThreadException sending an email from Android
7
Perhaps worth stressing the point that if you use a Service you will still need to create a separate thread - Service callbacks run on the main thread. An IntentService, on the other hand, runs its onHandleIntent method on a background thread.
– Stevie
Jan 22 '14 at 8:33
you should not use an AsyncTask for long running operations! Guidelines specify 2 to 3 seconds max.
– Dage
Feb 4 '14 at 10:41
add a comment |
- Do not use strictMode (only in debug mode)
- Do not change SDK version
- Do not use a separate thread
Use Service or AsyncTask
See also Stack Overflow question:
android.os.NetworkOnMainThreadException sending an email from Android
7
Perhaps worth stressing the point that if you use a Service you will still need to create a separate thread - Service callbacks run on the main thread. An IntentService, on the other hand, runs its onHandleIntent method on a background thread.
– Stevie
Jan 22 '14 at 8:33
you should not use an AsyncTask for long running operations! Guidelines specify 2 to 3 seconds max.
– Dage
Feb 4 '14 at 10:41
add a comment |
- Do not use strictMode (only in debug mode)
- Do not change SDK version
- Do not use a separate thread
Use Service or AsyncTask
See also Stack Overflow question:
android.os.NetworkOnMainThreadException sending an email from Android
- Do not use strictMode (only in debug mode)
- Do not change SDK version
- Do not use a separate thread
Use Service or AsyncTask
See also Stack Overflow question:
android.os.NetworkOnMainThreadException sending an email from Android
edited May 23 '17 at 12:26
Community♦
11
11
answered Aug 18 '13 at 9:18
venergiacvenergiac
4,24912650
4,24912650
7
Perhaps worth stressing the point that if you use a Service you will still need to create a separate thread - Service callbacks run on the main thread. An IntentService, on the other hand, runs its onHandleIntent method on a background thread.
– Stevie
Jan 22 '14 at 8:33
you should not use an AsyncTask for long running operations! Guidelines specify 2 to 3 seconds max.
– Dage
Feb 4 '14 at 10:41
add a comment |
7
Perhaps worth stressing the point that if you use a Service you will still need to create a separate thread - Service callbacks run on the main thread. An IntentService, on the other hand, runs its onHandleIntent method on a background thread.
– Stevie
Jan 22 '14 at 8:33
you should not use an AsyncTask for long running operations! Guidelines specify 2 to 3 seconds max.
– Dage
Feb 4 '14 at 10:41
7
7
Perhaps worth stressing the point that if you use a Service you will still need to create a separate thread - Service callbacks run on the main thread. An IntentService, on the other hand, runs its onHandleIntent method on a background thread.
– Stevie
Jan 22 '14 at 8:33
Perhaps worth stressing the point that if you use a Service you will still need to create a separate thread - Service callbacks run on the main thread. An IntentService, on the other hand, runs its onHandleIntent method on a background thread.
– Stevie
Jan 22 '14 at 8:33
you should not use an AsyncTask for long running operations! Guidelines specify 2 to 3 seconds max.
– Dage
Feb 4 '14 at 10:41
you should not use an AsyncTask for long running operations! Guidelines specify 2 to 3 seconds max.
– Dage
Feb 4 '14 at 10:41
add a comment |
Do the network actions on another thread
For Example:
new Thread(new Runnable(){
@Override
public void run() {
// Do network action in this function
}
}).start();
And add this to AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET"/>
4
But how can we find out when the thread finishes in this so that we can carry out the next set of tasks in the UI thread? The AsyncTask provides the facility to do that. Is there a way to do the same using runnable threads?
– Piyush Soni
Jan 4 '14 at 23:30
1
It will process your code step by step, so in the end of the code is finish, you need to use handler back to UI thread
– henry4343
Jan 5 '14 at 2:18
mobileorchard.com/…
– henry4343
Jan 6 '14 at 0:50
You can use async task or intent service, because it's execute on worker thread.
– Chetan Chaudhari
Apr 19 '17 at 20:05
add a comment |
Do the network actions on another thread
For Example:
new Thread(new Runnable(){
@Override
public void run() {
// Do network action in this function
}
}).start();
And add this to AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET"/>
4
But how can we find out when the thread finishes in this so that we can carry out the next set of tasks in the UI thread? The AsyncTask provides the facility to do that. Is there a way to do the same using runnable threads?
– Piyush Soni
Jan 4 '14 at 23:30
1
It will process your code step by step, so in the end of the code is finish, you need to use handler back to UI thread
– henry4343
Jan 5 '14 at 2:18
mobileorchard.com/…
– henry4343
Jan 6 '14 at 0:50
You can use async task or intent service, because it's execute on worker thread.
– Chetan Chaudhari
Apr 19 '17 at 20:05
add a comment |
Do the network actions on another thread
For Example:
new Thread(new Runnable(){
@Override
public void run() {
// Do network action in this function
}
}).start();
And add this to AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET"/>
Do the network actions on another thread
For Example:
new Thread(new Runnable(){
@Override
public void run() {
// Do network action in this function
}
}).start();
And add this to AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET"/>
edited Sep 13 '16 at 19:49


jose920405
5,72823050
5,72823050
answered Dec 24 '13 at 14:33


henry4343henry4343
2,63031526
2,63031526
4
But how can we find out when the thread finishes in this so that we can carry out the next set of tasks in the UI thread? The AsyncTask provides the facility to do that. Is there a way to do the same using runnable threads?
– Piyush Soni
Jan 4 '14 at 23:30
1
It will process your code step by step, so in the end of the code is finish, you need to use handler back to UI thread
– henry4343
Jan 5 '14 at 2:18
mobileorchard.com/…
– henry4343
Jan 6 '14 at 0:50
You can use async task or intent service, because it's execute on worker thread.
– Chetan Chaudhari
Apr 19 '17 at 20:05
add a comment |
4
But how can we find out when the thread finishes in this so that we can carry out the next set of tasks in the UI thread? The AsyncTask provides the facility to do that. Is there a way to do the same using runnable threads?
– Piyush Soni
Jan 4 '14 at 23:30
1
It will process your code step by step, so in the end of the code is finish, you need to use handler back to UI thread
– henry4343
Jan 5 '14 at 2:18
mobileorchard.com/…
– henry4343
Jan 6 '14 at 0:50
You can use async task or intent service, because it's execute on worker thread.
– Chetan Chaudhari
Apr 19 '17 at 20:05
4
4
But how can we find out when the thread finishes in this so that we can carry out the next set of tasks in the UI thread? The AsyncTask provides the facility to do that. Is there a way to do the same using runnable threads?
– Piyush Soni
Jan 4 '14 at 23:30
But how can we find out when the thread finishes in this so that we can carry out the next set of tasks in the UI thread? The AsyncTask provides the facility to do that. Is there a way to do the same using runnable threads?
– Piyush Soni
Jan 4 '14 at 23:30
1
1
It will process your code step by step, so in the end of the code is finish, you need to use handler back to UI thread
– henry4343
Jan 5 '14 at 2:18
It will process your code step by step, so in the end of the code is finish, you need to use handler back to UI thread
– henry4343
Jan 5 '14 at 2:18
mobileorchard.com/…
– henry4343
Jan 6 '14 at 0:50
mobileorchard.com/…
– henry4343
Jan 6 '14 at 0:50
You can use async task or intent service, because it's execute on worker thread.
– Chetan Chaudhari
Apr 19 '17 at 20:05
You can use async task or intent service, because it's execute on worker thread.
– Chetan Chaudhari
Apr 19 '17 at 20:05
add a comment |
You disable the strict mode using following code:
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy =
new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
This is not recommended: use the AsyncTask
interface.
Full code for both the methods
1
Yes ANR error would be come. means App not responding with in 5 sec.
– Muhammad Mubashir
May 6 '13 at 11:23
7
This is a really bad answer. You should not change the thread's policy but to write better code: do not make network operations on main thread!
– shkschneider
Aug 29 '13 at 15:01
6
Not good, but useful for POC / Debugging
– hB0
Nov 5 '13 at 15:26
@Sandeep You and other viewers should read this too. stackoverflow.com/a/18335031/3470479
– Prakhar1001
Sep 15 '16 at 14:06
add a comment |
You disable the strict mode using following code:
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy =
new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
This is not recommended: use the AsyncTask
interface.
Full code for both the methods
1
Yes ANR error would be come. means App not responding with in 5 sec.
– Muhammad Mubashir
May 6 '13 at 11:23
7
This is a really bad answer. You should not change the thread's policy but to write better code: do not make network operations on main thread!
– shkschneider
Aug 29 '13 at 15:01
6
Not good, but useful for POC / Debugging
– hB0
Nov 5 '13 at 15:26
@Sandeep You and other viewers should read this too. stackoverflow.com/a/18335031/3470479
– Prakhar1001
Sep 15 '16 at 14:06
add a comment |
You disable the strict mode using following code:
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy =
new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
This is not recommended: use the AsyncTask
interface.
Full code for both the methods
You disable the strict mode using following code:
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy =
new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
This is not recommended: use the AsyncTask
interface.
Full code for both the methods
edited Aug 20 '15 at 9:04
adamse
9,50932644
9,50932644
answered Oct 24 '12 at 7:10
SandeepSandeep
2,39043375
2,39043375
1
Yes ANR error would be come. means App not responding with in 5 sec.
– Muhammad Mubashir
May 6 '13 at 11:23
7
This is a really bad answer. You should not change the thread's policy but to write better code: do not make network operations on main thread!
– shkschneider
Aug 29 '13 at 15:01
6
Not good, but useful for POC / Debugging
– hB0
Nov 5 '13 at 15:26
@Sandeep You and other viewers should read this too. stackoverflow.com/a/18335031/3470479
– Prakhar1001
Sep 15 '16 at 14:06
add a comment |
1
Yes ANR error would be come. means App not responding with in 5 sec.
– Muhammad Mubashir
May 6 '13 at 11:23
7
This is a really bad answer. You should not change the thread's policy but to write better code: do not make network operations on main thread!
– shkschneider
Aug 29 '13 at 15:01
6
Not good, but useful for POC / Debugging
– hB0
Nov 5 '13 at 15:26
@Sandeep You and other viewers should read this too. stackoverflow.com/a/18335031/3470479
– Prakhar1001
Sep 15 '16 at 14:06
1
1
Yes ANR error would be come. means App not responding with in 5 sec.
– Muhammad Mubashir
May 6 '13 at 11:23
Yes ANR error would be come. means App not responding with in 5 sec.
– Muhammad Mubashir
May 6 '13 at 11:23
7
7
This is a really bad answer. You should not change the thread's policy but to write better code: do not make network operations on main thread!
– shkschneider
Aug 29 '13 at 15:01
This is a really bad answer. You should not change the thread's policy but to write better code: do not make network operations on main thread!
– shkschneider
Aug 29 '13 at 15:01
6
6
Not good, but useful for POC / Debugging
– hB0
Nov 5 '13 at 15:26
Not good, but useful for POC / Debugging
– hB0
Nov 5 '13 at 15:26
@Sandeep You and other viewers should read this too. stackoverflow.com/a/18335031/3470479
– Prakhar1001
Sep 15 '16 at 14:06
@Sandeep You and other viewers should read this too. stackoverflow.com/a/18335031/3470479
– Prakhar1001
Sep 15 '16 at 14:06
add a comment |
Network-based operations cannot be run on the main thread. You need to run all network-based tasks on a child thread or implement AsyncTask.
This is how you run a task in a child thread:
new Thread(new Runnable(){
@Override
public void run() {
try {
// Your implementation goes here
}
catch (Exception ex) {
ex.printStackTrace();
}
}
}).start();
Anonymous Runnable is NOT the best way, since it has an implicit reference to the enclosing class and preventing it from being GC ed until the thread completes! Also this thread will run at the Same Priority as the main/US thread, contending with lifecycle methods and UI frame rates!
– Yousha Aleayoub
Mar 12 '16 at 13:18
add a comment |
Network-based operations cannot be run on the main thread. You need to run all network-based tasks on a child thread or implement AsyncTask.
This is how you run a task in a child thread:
new Thread(new Runnable(){
@Override
public void run() {
try {
// Your implementation goes here
}
catch (Exception ex) {
ex.printStackTrace();
}
}
}).start();
Anonymous Runnable is NOT the best way, since it has an implicit reference to the enclosing class and preventing it from being GC ed until the thread completes! Also this thread will run at the Same Priority as the main/US thread, contending with lifecycle methods and UI frame rates!
– Yousha Aleayoub
Mar 12 '16 at 13:18
add a comment |
Network-based operations cannot be run on the main thread. You need to run all network-based tasks on a child thread or implement AsyncTask.
This is how you run a task in a child thread:
new Thread(new Runnable(){
@Override
public void run() {
try {
// Your implementation goes here
}
catch (Exception ex) {
ex.printStackTrace();
}
}
}).start();
Network-based operations cannot be run on the main thread. You need to run all network-based tasks on a child thread or implement AsyncTask.
This is how you run a task in a child thread:
new Thread(new Runnable(){
@Override
public void run() {
try {
// Your implementation goes here
}
catch (Exception ex) {
ex.printStackTrace();
}
}
}).start();
edited Jun 22 '16 at 21:08


Peter Mortensen
13.5k1984111
13.5k1984111
answered Jan 14 '14 at 6:14
Dhruv JindalDhruv Jindal
748716
748716
Anonymous Runnable is NOT the best way, since it has an implicit reference to the enclosing class and preventing it from being GC ed until the thread completes! Also this thread will run at the Same Priority as the main/US thread, contending with lifecycle methods and UI frame rates!
– Yousha Aleayoub
Mar 12 '16 at 13:18
add a comment |
Anonymous Runnable is NOT the best way, since it has an implicit reference to the enclosing class and preventing it from being GC ed until the thread completes! Also this thread will run at the Same Priority as the main/US thread, contending with lifecycle methods and UI frame rates!
– Yousha Aleayoub
Mar 12 '16 at 13:18
Anonymous Runnable is NOT the best way, since it has an implicit reference to the enclosing class and preventing it from being GC ed until the thread completes! Also this thread will run at the Same Priority as the main/US thread, contending with lifecycle methods and UI frame rates!
– Yousha Aleayoub
Mar 12 '16 at 13:18
Anonymous Runnable is NOT the best way, since it has an implicit reference to the enclosing class and preventing it from being GC ed until the thread completes! Also this thread will run at the Same Priority as the main/US thread, contending with lifecycle methods and UI frame rates!
– Yousha Aleayoub
Mar 12 '16 at 13:18
add a comment |
Put your code inside:
new Thread(new Runnable(){
@Override
public void run() {
try {
// Your implementation
}
catch (Exception ex) {
ex.printStackTrace();
}
}
}).start();
Or:
class DemoTask extends AsyncTask<Void, Void, Void> {
protected Void doInBackground(Void... arg0) {
//Your implementation
}
protected void onPostExecute(Void result) {
// TODO: do something with the feed
}
}
Second one ll be best than first for api above than 11
– Rohit Goswami
Jul 28 '14 at 10:52
read the comment under: stackoverflow.com/a/21107128/1429432
– Yousha Aleayoub
Mar 12 '16 at 13:19
Async Work on most case
– Ajay Pandya
Dec 9 '16 at 10:15
add a comment |
Put your code inside:
new Thread(new Runnable(){
@Override
public void run() {
try {
// Your implementation
}
catch (Exception ex) {
ex.printStackTrace();
}
}
}).start();
Or:
class DemoTask extends AsyncTask<Void, Void, Void> {
protected Void doInBackground(Void... arg0) {
//Your implementation
}
protected void onPostExecute(Void result) {
// TODO: do something with the feed
}
}
Second one ll be best than first for api above than 11
– Rohit Goswami
Jul 28 '14 at 10:52
read the comment under: stackoverflow.com/a/21107128/1429432
– Yousha Aleayoub
Mar 12 '16 at 13:19
Async Work on most case
– Ajay Pandya
Dec 9 '16 at 10:15
add a comment |
Put your code inside:
new Thread(new Runnable(){
@Override
public void run() {
try {
// Your implementation
}
catch (Exception ex) {
ex.printStackTrace();
}
}
}).start();
Or:
class DemoTask extends AsyncTask<Void, Void, Void> {
protected Void doInBackground(Void... arg0) {
//Your implementation
}
protected void onPostExecute(Void result) {
// TODO: do something with the feed
}
}
Put your code inside:
new Thread(new Runnable(){
@Override
public void run() {
try {
// Your implementation
}
catch (Exception ex) {
ex.printStackTrace();
}
}
}).start();
Or:
class DemoTask extends AsyncTask<Void, Void, Void> {
protected Void doInBackground(Void... arg0) {
//Your implementation
}
protected void onPostExecute(Void result) {
// TODO: do something with the feed
}
}
edited Jun 22 '16 at 21:13


Peter Mortensen
13.5k1984111
13.5k1984111
answered Jul 28 '14 at 10:43


Vaishali SutariyaVaishali Sutariya
3,7482028
3,7482028
Second one ll be best than first for api above than 11
– Rohit Goswami
Jul 28 '14 at 10:52
read the comment under: stackoverflow.com/a/21107128/1429432
– Yousha Aleayoub
Mar 12 '16 at 13:19
Async Work on most case
– Ajay Pandya
Dec 9 '16 at 10:15
add a comment |
Second one ll be best than first for api above than 11
– Rohit Goswami
Jul 28 '14 at 10:52
read the comment under: stackoverflow.com/a/21107128/1429432
– Yousha Aleayoub
Mar 12 '16 at 13:19
Async Work on most case
– Ajay Pandya
Dec 9 '16 at 10:15
Second one ll be best than first for api above than 11
– Rohit Goswami
Jul 28 '14 at 10:52
Second one ll be best than first for api above than 11
– Rohit Goswami
Jul 28 '14 at 10:52
read the comment under: stackoverflow.com/a/21107128/1429432
– Yousha Aleayoub
Mar 12 '16 at 13:19
read the comment under: stackoverflow.com/a/21107128/1429432
– Yousha Aleayoub
Mar 12 '16 at 13:19
Async Work on most case
– Ajay Pandya
Dec 9 '16 at 10:15
Async Work on most case
– Ajay Pandya
Dec 9 '16 at 10:15
add a comment |
Using Android Annotations is an option. It will allow you to simply run any method in a background thread:
// normal method
private void normal() {
doSomething(); // do something in background
}
@Background
protected void doSomething()
// run your networking code here
}
Note, that although it provides benefits of simplicity and readability, it has its disadvantages.
1
what are the disadvantages?
– Gavriel
Aug 15 '15 at 20:00
5
@Gavriel it creates duplicates of everything you annotate, whether it's a method, activity, fragment, singleton etc, so there is twice as much code and it takes longer to compile it. It may also have some issues due to bugs in the library. Debugging and finding errors would become more difficult.
– Oleksiy
Aug 19 '15 at 1:30
add a comment |
Using Android Annotations is an option. It will allow you to simply run any method in a background thread:
// normal method
private void normal() {
doSomething(); // do something in background
}
@Background
protected void doSomething()
// run your networking code here
}
Note, that although it provides benefits of simplicity and readability, it has its disadvantages.
1
what are the disadvantages?
– Gavriel
Aug 15 '15 at 20:00
5
@Gavriel it creates duplicates of everything you annotate, whether it's a method, activity, fragment, singleton etc, so there is twice as much code and it takes longer to compile it. It may also have some issues due to bugs in the library. Debugging and finding errors would become more difficult.
– Oleksiy
Aug 19 '15 at 1:30
add a comment |
Using Android Annotations is an option. It will allow you to simply run any method in a background thread:
// normal method
private void normal() {
doSomething(); // do something in background
}
@Background
protected void doSomething()
// run your networking code here
}
Note, that although it provides benefits of simplicity and readability, it has its disadvantages.
Using Android Annotations is an option. It will allow you to simply run any method in a background thread:
// normal method
private void normal() {
doSomething(); // do something in background
}
@Background
protected void doSomething()
// run your networking code here
}
Note, that although it provides benefits of simplicity and readability, it has its disadvantages.
edited Apr 30 '15 at 16:46
answered Jun 12 '14 at 3:10
OleksiyOleksiy
15.1k1855104
15.1k1855104
1
what are the disadvantages?
– Gavriel
Aug 15 '15 at 20:00
5
@Gavriel it creates duplicates of everything you annotate, whether it's a method, activity, fragment, singleton etc, so there is twice as much code and it takes longer to compile it. It may also have some issues due to bugs in the library. Debugging and finding errors would become more difficult.
– Oleksiy
Aug 19 '15 at 1:30
add a comment |
1
what are the disadvantages?
– Gavriel
Aug 15 '15 at 20:00
5
@Gavriel it creates duplicates of everything you annotate, whether it's a method, activity, fragment, singleton etc, so there is twice as much code and it takes longer to compile it. It may also have some issues due to bugs in the library. Debugging and finding errors would become more difficult.
– Oleksiy
Aug 19 '15 at 1:30
1
1
what are the disadvantages?
– Gavriel
Aug 15 '15 at 20:00
what are the disadvantages?
– Gavriel
Aug 15 '15 at 20:00
5
5
@Gavriel it creates duplicates of everything you annotate, whether it's a method, activity, fragment, singleton etc, so there is twice as much code and it takes longer to compile it. It may also have some issues due to bugs in the library. Debugging and finding errors would become more difficult.
– Oleksiy
Aug 19 '15 at 1:30
@Gavriel it creates duplicates of everything you annotate, whether it's a method, activity, fragment, singleton etc, so there is twice as much code and it takes longer to compile it. It may also have some issues due to bugs in the library. Debugging and finding errors would become more difficult.
– Oleksiy
Aug 19 '15 at 1:30
add a comment |
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.
add a comment |
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.
add a comment |
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.
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.
edited Feb 9 '14 at 16:27


Peter Mortensen
13.5k1984111
13.5k1984111
answered Sep 5 '13 at 8:16
raihan ahmedraihan ahmed
39133
39133
add a comment |
add a comment |
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 the Message
.
To simplify all these things, Android provides various ways, like AsyncTask
, AsyncTaskLoader
, CursorLoader
or IntentService
. So you can use any of these according to your requirements.
add a comment |
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 the Message
.
To simplify all these things, Android provides various ways, like AsyncTask
, AsyncTaskLoader
, CursorLoader
or IntentService
. So you can use any of these according to your requirements.
add a comment |
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 the Message
.
To simplify all these things, Android provides various ways, like AsyncTask
, AsyncTaskLoader
, CursorLoader
or IntentService
. So you can use any of these according to your requirements.
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 the Message
.
To simplify all these things, Android provides various ways, like AsyncTask
, AsyncTaskLoader
, CursorLoader
or IntentService
. So you can use any of these according to your requirements.
edited Feb 9 '14 at 16:29


Peter Mortensen
13.5k1984111
13.5k1984111
answered Jan 5 '14 at 18:28


Kapil VatsKapil Vats
4,83412129
4,83412129
add a comment |
add a comment |
The top answer of spektom works perfect.
If you are writing the AsyncTask
inline and not extending as a class, and on top of this, if there is a need to get a response out of the AsyncTask
, one can use the get()
method as below.
RSSFeed feed = new RetreiveFeedTask().execute(urlToRssFeed).get();
(From his example.)
5
usingget()
is a bad idea ... it makes AsyncTask "sync" again
– Selvin
Sep 17 '13 at 15:29
Is there a better different way out of it? @Selvin
– sivag1
Sep 20 '13 at 20:50
2
I think you could info the main thread about the result.For example,send a broadcast to main thread including the result.
– Chine Gary
Feb 10 '15 at 2:35
add a comment |
The top answer of spektom works perfect.
If you are writing the AsyncTask
inline and not extending as a class, and on top of this, if there is a need to get a response out of the AsyncTask
, one can use the get()
method as below.
RSSFeed feed = new RetreiveFeedTask().execute(urlToRssFeed).get();
(From his example.)
5
usingget()
is a bad idea ... it makes AsyncTask "sync" again
– Selvin
Sep 17 '13 at 15:29
Is there a better different way out of it? @Selvin
– sivag1
Sep 20 '13 at 20:50
2
I think you could info the main thread about the result.For example,send a broadcast to main thread including the result.
– Chine Gary
Feb 10 '15 at 2:35
add a comment |
The top answer of spektom works perfect.
If you are writing the AsyncTask
inline and not extending as a class, and on top of this, if there is a need to get a response out of the AsyncTask
, one can use the get()
method as below.
RSSFeed feed = new RetreiveFeedTask().execute(urlToRssFeed).get();
(From his example.)
The top answer of spektom works perfect.
If you are writing the AsyncTask
inline and not extending as a class, and on top of this, if there is a need to get a response out of the AsyncTask
, one can use the get()
method as below.
RSSFeed feed = new RetreiveFeedTask().execute(urlToRssFeed).get();
(From his example.)
edited May 23 '17 at 11:47
Community♦
11
11
answered Jul 18 '13 at 18:52
sivag1sivag1
3,14921830
3,14921830
5
usingget()
is a bad idea ... it makes AsyncTask "sync" again
– Selvin
Sep 17 '13 at 15:29
Is there a better different way out of it? @Selvin
– sivag1
Sep 20 '13 at 20:50
2
I think you could info the main thread about the result.For example,send a broadcast to main thread including the result.
– Chine Gary
Feb 10 '15 at 2:35
add a comment |
5
usingget()
is a bad idea ... it makes AsyncTask "sync" again
– Selvin
Sep 17 '13 at 15:29
Is there a better different way out of it? @Selvin
– sivag1
Sep 20 '13 at 20:50
2
I think you could info the main thread about the result.For example,send a broadcast to main thread including the result.
– Chine Gary
Feb 10 '15 at 2:35
5
5
using
get()
is a bad idea ... it makes AsyncTask "sync" again– Selvin
Sep 17 '13 at 15:29
using
get()
is a bad idea ... it makes AsyncTask "sync" again– Selvin
Sep 17 '13 at 15:29
Is there a better different way out of it? @Selvin
– sivag1
Sep 20 '13 at 20:50
Is there a better different way out of it? @Selvin
– sivag1
Sep 20 '13 at 20:50
2
2
I think you could info the main thread about the result.For example,send a broadcast to main thread including the result.
– Chine Gary
Feb 10 '15 at 2:35
I think you could info the main thread about the result.For example,send a broadcast to main thread including the result.
– Chine Gary
Feb 10 '15 at 2:35
add a comment |
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.
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
}
});
add a comment |
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.
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
}
});
add a comment |
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.
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
}
});
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.
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
}
});
edited Sep 7 '17 at 4:53
answered Jul 16 '14 at 6:09


Ashwin S AshokAshwin S Ashok
2,49712028
2,49712028
add a comment |
add a comment |
This is only thrown for applications targeting the Honeycomb SDK or higher. Applications targeting earlier SDK versions are allowed to do networking on their main event loop threads.
The error is the SDK warning!
add a comment |
This is only thrown for applications targeting the Honeycomb SDK or higher. Applications targeting earlier SDK versions are allowed to do networking on their main event loop threads.
The error is the SDK warning!
add a comment |
This is only thrown for applications targeting the Honeycomb SDK or higher. Applications targeting earlier SDK versions are allowed to do networking on their main event loop threads.
The error is the SDK warning!
This is only thrown for applications targeting the Honeycomb SDK or higher. Applications targeting earlier SDK versions are allowed to do networking on their main event loop threads.
The error is the SDK warning!
edited Jun 22 '16 at 21:09


Peter Mortensen
13.5k1984111
13.5k1984111
answered Feb 25 '14 at 6:23


perryperry
6981820
6981820
add a comment |
add a comment |
For me it was this:
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="10" />
The device I was testing my app on was 4.1.2 which is SDK Version 16!
Make the sure the target version is the same as your Android Target Library. If you are unsure what your target library is, right click your Project -> Build Path -> Android, and it should be the one that is ticked.
Also, as others have mentioned, include the correct permissions to access the Internet:
<uses-permission android:name="android.permission.INTERNET"/>
11
Let me explain you what you are doing here:NetworkOnMainThreadException
is the Guardian which is telling you: do not shoot at your own foot ... your solution is: let's go back to the past when there was no Guardian - now i can shoot at my foot freely
– Selvin
Sep 17 '13 at 15:36
1
I took this approach, too, and didn't have any problems. Guardian is too fussy sometimes.
– FractalBob
Oct 25 '13 at 19:36
add a comment |
For me it was this:
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="10" />
The device I was testing my app on was 4.1.2 which is SDK Version 16!
Make the sure the target version is the same as your Android Target Library. If you are unsure what your target library is, right click your Project -> Build Path -> Android, and it should be the one that is ticked.
Also, as others have mentioned, include the correct permissions to access the Internet:
<uses-permission android:name="android.permission.INTERNET"/>
11
Let me explain you what you are doing here:NetworkOnMainThreadException
is the Guardian which is telling you: do not shoot at your own foot ... your solution is: let's go back to the past when there was no Guardian - now i can shoot at my foot freely
– Selvin
Sep 17 '13 at 15:36
1
I took this approach, too, and didn't have any problems. Guardian is too fussy sometimes.
– FractalBob
Oct 25 '13 at 19:36
add a comment |
For me it was this:
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="10" />
The device I was testing my app on was 4.1.2 which is SDK Version 16!
Make the sure the target version is the same as your Android Target Library. If you are unsure what your target library is, right click your Project -> Build Path -> Android, and it should be the one that is ticked.
Also, as others have mentioned, include the correct permissions to access the Internet:
<uses-permission android:name="android.permission.INTERNET"/>
For me it was this:
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="10" />
The device I was testing my app on was 4.1.2 which is SDK Version 16!
Make the sure the target version is the same as your Android Target Library. If you are unsure what your target library is, right click your Project -> Build Path -> Android, and it should be the one that is ticked.
Also, as others have mentioned, include the correct permissions to access the Internet:
<uses-permission android:name="android.permission.INTERNET"/>
edited Jun 22 '16 at 21:07


Peter Mortensen
13.5k1984111
13.5k1984111
answered Sep 17 '13 at 12:15
rharveyrharvey
1,50912022
1,50912022
11
Let me explain you what you are doing here:NetworkOnMainThreadException
is the Guardian which is telling you: do not shoot at your own foot ... your solution is: let's go back to the past when there was no Guardian - now i can shoot at my foot freely
– Selvin
Sep 17 '13 at 15:36
1
I took this approach, too, and didn't have any problems. Guardian is too fussy sometimes.
– FractalBob
Oct 25 '13 at 19:36
add a comment |
11
Let me explain you what you are doing here:NetworkOnMainThreadException
is the Guardian which is telling you: do not shoot at your own foot ... your solution is: let's go back to the past when there was no Guardian - now i can shoot at my foot freely
– Selvin
Sep 17 '13 at 15:36
1
I took this approach, too, and didn't have any problems. Guardian is too fussy sometimes.
– FractalBob
Oct 25 '13 at 19:36
11
11
Let me explain you what you are doing here:
NetworkOnMainThreadException
is the Guardian which is telling you: do not shoot at your own foot ... your solution is: let's go back to the past when there was no Guardian - now i can shoot at my foot freely– Selvin
Sep 17 '13 at 15:36
Let me explain you what you are doing here:
NetworkOnMainThreadException
is the Guardian which is telling you: do not shoot at your own foot ... your solution is: let's go back to the past when there was no Guardian - now i can shoot at my foot freely– Selvin
Sep 17 '13 at 15:36
1
1
I took this approach, too, and didn't have any problems. Guardian is too fussy sometimes.
– FractalBob
Oct 25 '13 at 19:36
I took this approach, too, and didn't have any problems. Guardian is too fussy sometimes.
– FractalBob
Oct 25 '13 at 19:36
add a comment |
Just to spell out something explicitly:
The main thread is basically the UI thread.
So saying that you cannot do networking operations in the main thread means you cannot do networking operations in the UI thread, which means you cannot do networking operations in a *runOnUiThread(new Runnable() { ... }*
block inside some other thread, either.
(I just had a long head-scratching moment trying to figure out why I was getting that error somewhere other than my main thread. This was why; this thread helped; and hopefully this comment will help someone else.)
add a comment |
Just to spell out something explicitly:
The main thread is basically the UI thread.
So saying that you cannot do networking operations in the main thread means you cannot do networking operations in the UI thread, which means you cannot do networking operations in a *runOnUiThread(new Runnable() { ... }*
block inside some other thread, either.
(I just had a long head-scratching moment trying to figure out why I was getting that error somewhere other than my main thread. This was why; this thread helped; and hopefully this comment will help someone else.)
add a comment |
Just to spell out something explicitly:
The main thread is basically the UI thread.
So saying that you cannot do networking operations in the main thread means you cannot do networking operations in the UI thread, which means you cannot do networking operations in a *runOnUiThread(new Runnable() { ... }*
block inside some other thread, either.
(I just had a long head-scratching moment trying to figure out why I was getting that error somewhere other than my main thread. This was why; this thread helped; and hopefully this comment will help someone else.)
Just to spell out something explicitly:
The main thread is basically the UI thread.
So saying that you cannot do networking operations in the main thread means you cannot do networking operations in the UI thread, which means you cannot do networking operations in a *runOnUiThread(new Runnable() { ... }*
block inside some other thread, either.
(I just had a long head-scratching moment trying to figure out why I was getting that error somewhere other than my main thread. This was why; this thread helped; and hopefully this comment will help someone else.)
answered Jun 24 '14 at 21:32
NovakNovak
3,29811438
3,29811438
add a comment |
add a comment |
This exception occurs due to any heavy task performed on the main thread if that performing task takes too much time.
To avoid this, we can handle it using threads or executers
Executors.newSingleThreadExecutor().submit(new Runnable() {
@Override
public void run() {
// You can perform your task here.
}
});
add a comment |
This exception occurs due to any heavy task performed on the main thread if that performing task takes too much time.
To avoid this, we can handle it using threads or executers
Executors.newSingleThreadExecutor().submit(new Runnable() {
@Override
public void run() {
// You can perform your task here.
}
});
add a comment |
This exception occurs due to any heavy task performed on the main thread if that performing task takes too much time.
To avoid this, we can handle it using threads or executers
Executors.newSingleThreadExecutor().submit(new Runnable() {
@Override
public void run() {
// You can perform your task here.
}
});
This exception occurs due to any heavy task performed on the main thread if that performing task takes too much time.
To avoid this, we can handle it using threads or executers
Executors.newSingleThreadExecutor().submit(new Runnable() {
@Override
public void run() {
// You can perform your task here.
}
});
edited Jun 22 '16 at 21:12


Peter Mortensen
13.5k1984111
13.5k1984111
answered Jul 21 '14 at 11:53


amardeepamardeep
322316
322316
add a comment |
add a comment |
Use this in Your Activity
btnsub.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
//Initialize soap request + add parameters
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME1);
//Use this to add parameters
request.addProperty("pincode", txtpincode.getText().toString());
request.addProperty("bg", bloodgroup.getSelectedItem().toString());
//Declare the version of the SOAP request
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.setOutputSoapObject(request);
envelope.dotNet = true;
try {
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
//this is the actual part that will call the webservice
androidHttpTransport.call(SOAP_ACTION1, envelope);
// Get the SoapResult from the envelope body.
SoapObject result = (SoapObject) envelope.getResponse();
Log.e("result data", "data" + result);
SoapObject root = (SoapObject) result.getProperty(0);
// SoapObject s_deals = (SoapObject) root.getProperty(0);
// SoapObject s_deals_1 = (SoapObject) s_deals.getProperty(0);
//
System.out.println("********Count : " + root.getPropertyCount());
value = new ArrayList<Detailinfo>();
for (int i = 0; i < root.getPropertyCount(); i++) {
SoapObject s_deals = (SoapObject) root.getProperty(i);
Detailinfo info = new Detailinfo();
info.setFirstName(s_deals.getProperty("Firstname").toString());
info.setLastName(s_deals.getProperty("Lastname").toString());
info.setDOB(s_deals.getProperty("DOB").toString());
info.setGender(s_deals.getProperty("Gender").toString());
info.setAddress(s_deals.getProperty("Address").toString());
info.setCity(s_deals.getProperty("City").toString());
info.setState(s_deals.getProperty("State").toString());
info.setPinecode(s_deals.getProperty("Pinecode").toString());
info.setMobile(s_deals.getProperty("Mobile").toString());
info.setEmail(s_deals.getProperty("Email").toString());
info.setBloodgroup(s_deals.getProperty("Bloodgroup").toString());
info.setAdddate(s_deals.getProperty("Adddate").toString());
info.setWaight(s_deals.getProperty("waight").toString());
value.add(info);
}
} catch (Exception e) {
e.printStackTrace();
}
Intent intent = new Intent(getApplicationContext(), ComposeMail.class);
//intent.putParcelableArrayListExtra("valuesList", value);
startActivity(intent);
}
}).start();
}
});
add a comment |
Use this in Your Activity
btnsub.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
//Initialize soap request + add parameters
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME1);
//Use this to add parameters
request.addProperty("pincode", txtpincode.getText().toString());
request.addProperty("bg", bloodgroup.getSelectedItem().toString());
//Declare the version of the SOAP request
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.setOutputSoapObject(request);
envelope.dotNet = true;
try {
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
//this is the actual part that will call the webservice
androidHttpTransport.call(SOAP_ACTION1, envelope);
// Get the SoapResult from the envelope body.
SoapObject result = (SoapObject) envelope.getResponse();
Log.e("result data", "data" + result);
SoapObject root = (SoapObject) result.getProperty(0);
// SoapObject s_deals = (SoapObject) root.getProperty(0);
// SoapObject s_deals_1 = (SoapObject) s_deals.getProperty(0);
//
System.out.println("********Count : " + root.getPropertyCount());
value = new ArrayList<Detailinfo>();
for (int i = 0; i < root.getPropertyCount(); i++) {
SoapObject s_deals = (SoapObject) root.getProperty(i);
Detailinfo info = new Detailinfo();
info.setFirstName(s_deals.getProperty("Firstname").toString());
info.setLastName(s_deals.getProperty("Lastname").toString());
info.setDOB(s_deals.getProperty("DOB").toString());
info.setGender(s_deals.getProperty("Gender").toString());
info.setAddress(s_deals.getProperty("Address").toString());
info.setCity(s_deals.getProperty("City").toString());
info.setState(s_deals.getProperty("State").toString());
info.setPinecode(s_deals.getProperty("Pinecode").toString());
info.setMobile(s_deals.getProperty("Mobile").toString());
info.setEmail(s_deals.getProperty("Email").toString());
info.setBloodgroup(s_deals.getProperty("Bloodgroup").toString());
info.setAdddate(s_deals.getProperty("Adddate").toString());
info.setWaight(s_deals.getProperty("waight").toString());
value.add(info);
}
} catch (Exception e) {
e.printStackTrace();
}
Intent intent = new Intent(getApplicationContext(), ComposeMail.class);
//intent.putParcelableArrayListExtra("valuesList", value);
startActivity(intent);
}
}).start();
}
});
add a comment |
Use this in Your Activity
btnsub.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
//Initialize soap request + add parameters
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME1);
//Use this to add parameters
request.addProperty("pincode", txtpincode.getText().toString());
request.addProperty("bg", bloodgroup.getSelectedItem().toString());
//Declare the version of the SOAP request
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.setOutputSoapObject(request);
envelope.dotNet = true;
try {
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
//this is the actual part that will call the webservice
androidHttpTransport.call(SOAP_ACTION1, envelope);
// Get the SoapResult from the envelope body.
SoapObject result = (SoapObject) envelope.getResponse();
Log.e("result data", "data" + result);
SoapObject root = (SoapObject) result.getProperty(0);
// SoapObject s_deals = (SoapObject) root.getProperty(0);
// SoapObject s_deals_1 = (SoapObject) s_deals.getProperty(0);
//
System.out.println("********Count : " + root.getPropertyCount());
value = new ArrayList<Detailinfo>();
for (int i = 0; i < root.getPropertyCount(); i++) {
SoapObject s_deals = (SoapObject) root.getProperty(i);
Detailinfo info = new Detailinfo();
info.setFirstName(s_deals.getProperty("Firstname").toString());
info.setLastName(s_deals.getProperty("Lastname").toString());
info.setDOB(s_deals.getProperty("DOB").toString());
info.setGender(s_deals.getProperty("Gender").toString());
info.setAddress(s_deals.getProperty("Address").toString());
info.setCity(s_deals.getProperty("City").toString());
info.setState(s_deals.getProperty("State").toString());
info.setPinecode(s_deals.getProperty("Pinecode").toString());
info.setMobile(s_deals.getProperty("Mobile").toString());
info.setEmail(s_deals.getProperty("Email").toString());
info.setBloodgroup(s_deals.getProperty("Bloodgroup").toString());
info.setAdddate(s_deals.getProperty("Adddate").toString());
info.setWaight(s_deals.getProperty("waight").toString());
value.add(info);
}
} catch (Exception e) {
e.printStackTrace();
}
Intent intent = new Intent(getApplicationContext(), ComposeMail.class);
//intent.putParcelableArrayListExtra("valuesList", value);
startActivity(intent);
}
}).start();
}
});
Use this in Your Activity
btnsub.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
//Initialize soap request + add parameters
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME1);
//Use this to add parameters
request.addProperty("pincode", txtpincode.getText().toString());
request.addProperty("bg", bloodgroup.getSelectedItem().toString());
//Declare the version of the SOAP request
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.setOutputSoapObject(request);
envelope.dotNet = true;
try {
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
//this is the actual part that will call the webservice
androidHttpTransport.call(SOAP_ACTION1, envelope);
// Get the SoapResult from the envelope body.
SoapObject result = (SoapObject) envelope.getResponse();
Log.e("result data", "data" + result);
SoapObject root = (SoapObject) result.getProperty(0);
// SoapObject s_deals = (SoapObject) root.getProperty(0);
// SoapObject s_deals_1 = (SoapObject) s_deals.getProperty(0);
//
System.out.println("********Count : " + root.getPropertyCount());
value = new ArrayList<Detailinfo>();
for (int i = 0; i < root.getPropertyCount(); i++) {
SoapObject s_deals = (SoapObject) root.getProperty(i);
Detailinfo info = new Detailinfo();
info.setFirstName(s_deals.getProperty("Firstname").toString());
info.setLastName(s_deals.getProperty("Lastname").toString());
info.setDOB(s_deals.getProperty("DOB").toString());
info.setGender(s_deals.getProperty("Gender").toString());
info.setAddress(s_deals.getProperty("Address").toString());
info.setCity(s_deals.getProperty("City").toString());
info.setState(s_deals.getProperty("State").toString());
info.setPinecode(s_deals.getProperty("Pinecode").toString());
info.setMobile(s_deals.getProperty("Mobile").toString());
info.setEmail(s_deals.getProperty("Email").toString());
info.setBloodgroup(s_deals.getProperty("Bloodgroup").toString());
info.setAdddate(s_deals.getProperty("Adddate").toString());
info.setWaight(s_deals.getProperty("waight").toString());
value.add(info);
}
} catch (Exception e) {
e.printStackTrace();
}
Intent intent = new Intent(getApplicationContext(), ComposeMail.class);
//intent.putParcelableArrayListExtra("valuesList", value);
startActivity(intent);
}
}).start();
}
});
edited Dec 3 '18 at 12:07


Catalina T.
2,5471225
2,5471225
answered Mar 1 '14 at 13:43


dhiraj kakrandhiraj kakran
3041419
3041419
add a comment |
add a comment |
In simple words,
DO NOT DO NETWORK WORK IN THE UI THREAD
For example, if you do an HTTP request, that is a network action.
Solution:
- You have to create a new Thread
Or use AsyncTask class
Way:
Put all your works inside
run()
method of new thread
OrdoInBackground()
method of AsyncTask class.
But:
When you get something from Network response and want to show it on your view (like display response message in TextView), you need to return back to the UI thread.
If you don't do it, you will get ViewRootImpl$CalledFromWrongThreadException
.
How to?
- While using AsyncTask, update view from
onPostExecute()
method
Or callrunOnUiThread()
method and update view inside therun()
method.
add a comment |
In simple words,
DO NOT DO NETWORK WORK IN THE UI THREAD
For example, if you do an HTTP request, that is a network action.
Solution:
- You have to create a new Thread
Or use AsyncTask class
Way:
Put all your works inside
run()
method of new thread
OrdoInBackground()
method of AsyncTask class.
But:
When you get something from Network response and want to show it on your view (like display response message in TextView), you need to return back to the UI thread.
If you don't do it, you will get ViewRootImpl$CalledFromWrongThreadException
.
How to?
- While using AsyncTask, update view from
onPostExecute()
method
Or callrunOnUiThread()
method and update view inside therun()
method.
add a comment |
In simple words,
DO NOT DO NETWORK WORK IN THE UI THREAD
For example, if you do an HTTP request, that is a network action.
Solution:
- You have to create a new Thread
Or use AsyncTask class
Way:
Put all your works inside
run()
method of new thread
OrdoInBackground()
method of AsyncTask class.
But:
When you get something from Network response and want to show it on your view (like display response message in TextView), you need to return back to the UI thread.
If you don't do it, you will get ViewRootImpl$CalledFromWrongThreadException
.
How to?
- While using AsyncTask, update view from
onPostExecute()
method
Or callrunOnUiThread()
method and update view inside therun()
method.
In simple words,
DO NOT DO NETWORK WORK IN THE UI THREAD
For example, if you do an HTTP request, that is a network action.
Solution:
- You have to create a new Thread
Or use AsyncTask class
Way:
Put all your works inside
run()
method of new thread
OrdoInBackground()
method of AsyncTask class.
But:
When you get something from Network response and want to show it on your view (like display response message in TextView), you need to return back to the UI thread.
If you don't do it, you will get ViewRootImpl$CalledFromWrongThreadException
.
How to?
- While using AsyncTask, update view from
onPostExecute()
method
Or callrunOnUiThread()
method and update view inside therun()
method.
edited May 23 '17 at 12:10
Community♦
11
11
answered Jul 22 '15 at 2:05
NabinNabin
6,07653970
6,07653970
add a comment |
add a comment |
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:
http://api.example.com/stocks //ResponseWrapper<String> object containing a list of Srings with ticker symbols
http://api.example.com/stocks/$symbol //Stock object
http://api.example.com/stocks/$symbol/prices //PriceHistory<Stock> object
http://api.example.com/currencies //ResponseWrapper<String> object containing a list of currency abbreviation
http://api.example.com/currencies/$currency //Currency object
http://api.example.com/currencies/$id1/values/$id2 //PriceHistory<Currency> object comparing the prices of the first currency (id1) to the second (id2)
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:
implementation 'com.squareup.retrofit2:retrofit:2.3.0' //retrofit library, current as of September 21, 2017
implementation 'com.squareup.retrofit2:converter-gson:2.3.0' //gson serialization and deserialization support for retrofit, version must match retrofit version
FinancesApi.java
public interface FinancesApi {
@GET("stocks")
Call<ResponseWrapper<String>> listStocks();
@GET("stocks/{symbol}")
Call<Stock> getStock(@Path("symbol")String tickerSymbol);
@GET("stocks/{symbol}/prices")
Call<PriceHistory<Stock>> getPriceHistory(@Path("symbol")String tickerSymbol);
@GET("currencies")
Call<ResponseWrapper<String>> listCurrencies();
@GET("currencies/{symbol}")
Call<Currency> getCurrency(@Path("symbol")String currencySymbol);
@GET("currencies/{symbol}/values/{compare_symbol}")
Call<PriceHistory<Currency>> getComparativeHistory(@Path("symbol")String currency, @Path("compare_symbol")String currencyToPriceAgainst);
}
FinancesApiBuilder
public class FinancesApiBuilder {
public static FinancesApi build(String baseUrl){
return new Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(FinancesApi.class);
}
}
FinancesFragment snippet
FinancesApi api = FinancesApiBuilder.build("http://api.example.com/"); //trailing '/' required for predictable behavior
api.getStock("INTC").enqueue(new Callback<Stock>(){
@Override
public void onResponse(Call<Stock> stockCall, Response<Stock> stockResponse){
Stock stock = stockCall.body();
//do something with the stock
}
@Override
public void onResponse(Call<Stock> stockCall, Throwable t){
//something bad happened
}
}
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:
implementation 'com.android.volley:volley:1.0.0'
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:
public class ImageFetch {
private static ImageLoader imageLoader = null;
private static RequestQueue imageQueue = null;
public static ImageLoader getImageLoader(Context ctx){
if(imageLoader == null){
if(imageQueue == null){
imageQueue = Volley.newRequestQueue(ctx.getApplicationContext());
}
imageLoader = new ImageLoader(imageQueue, new ImageLoader.ImageCache() {
Map<String, Bitmap> cache = new HashMap<String, Bitmap>();
@Override
public Bitmap getBitmap(String url) {
return cache.get(url);
}
@Override
public void putBitmap(String url, Bitmap bitmap) {
cache.put(url, bitmap);
}
});
}
return imageLoader;
}
}
user_view_dialog.xml
Add the following to your layout xml file to add an image:
<com.android.volley.toolbox.NetworkImageView
android:id="@+id/profile_picture"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
app:srcCompat="@android:drawable/spinner_background"/>
UserViewDialog.java
Add the following code to the onCreate method (Fragment, Activity) or the constructor (Dialog):
NetworkImageView profilePicture = view.findViewById(R.id.profile_picture);
profilePicture.setImageUrl("http://example.com/users/images/profile.jpg", ImageFetch.getImageLoader(getContext());
Picasso
Another excellent library from Square. Please see the site for some great examples: http://square.github.io/picasso/
this should be the better answer than the original one as it simplifies the implementation of networking on android in the present world 2017, and most of the real world application uses very good libraries like these.
– Rakibul Haq
Nov 28 '17 at 11:46
add a comment |
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:
http://api.example.com/stocks //ResponseWrapper<String> object containing a list of Srings with ticker symbols
http://api.example.com/stocks/$symbol //Stock object
http://api.example.com/stocks/$symbol/prices //PriceHistory<Stock> object
http://api.example.com/currencies //ResponseWrapper<String> object containing a list of currency abbreviation
http://api.example.com/currencies/$currency //Currency object
http://api.example.com/currencies/$id1/values/$id2 //PriceHistory<Currency> object comparing the prices of the first currency (id1) to the second (id2)
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:
implementation 'com.squareup.retrofit2:retrofit:2.3.0' //retrofit library, current as of September 21, 2017
implementation 'com.squareup.retrofit2:converter-gson:2.3.0' //gson serialization and deserialization support for retrofit, version must match retrofit version
FinancesApi.java
public interface FinancesApi {
@GET("stocks")
Call<ResponseWrapper<String>> listStocks();
@GET("stocks/{symbol}")
Call<Stock> getStock(@Path("symbol")String tickerSymbol);
@GET("stocks/{symbol}/prices")
Call<PriceHistory<Stock>> getPriceHistory(@Path("symbol")String tickerSymbol);
@GET("currencies")
Call<ResponseWrapper<String>> listCurrencies();
@GET("currencies/{symbol}")
Call<Currency> getCurrency(@Path("symbol")String currencySymbol);
@GET("currencies/{symbol}/values/{compare_symbol}")
Call<PriceHistory<Currency>> getComparativeHistory(@Path("symbol")String currency, @Path("compare_symbol")String currencyToPriceAgainst);
}
FinancesApiBuilder
public class FinancesApiBuilder {
public static FinancesApi build(String baseUrl){
return new Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(FinancesApi.class);
}
}
FinancesFragment snippet
FinancesApi api = FinancesApiBuilder.build("http://api.example.com/"); //trailing '/' required for predictable behavior
api.getStock("INTC").enqueue(new Callback<Stock>(){
@Override
public void onResponse(Call<Stock> stockCall, Response<Stock> stockResponse){
Stock stock = stockCall.body();
//do something with the stock
}
@Override
public void onResponse(Call<Stock> stockCall, Throwable t){
//something bad happened
}
}
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:
implementation 'com.android.volley:volley:1.0.0'
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:
public class ImageFetch {
private static ImageLoader imageLoader = null;
private static RequestQueue imageQueue = null;
public static ImageLoader getImageLoader(Context ctx){
if(imageLoader == null){
if(imageQueue == null){
imageQueue = Volley.newRequestQueue(ctx.getApplicationContext());
}
imageLoader = new ImageLoader(imageQueue, new ImageLoader.ImageCache() {
Map<String, Bitmap> cache = new HashMap<String, Bitmap>();
@Override
public Bitmap getBitmap(String url) {
return cache.get(url);
}
@Override
public void putBitmap(String url, Bitmap bitmap) {
cache.put(url, bitmap);
}
});
}
return imageLoader;
}
}
user_view_dialog.xml
Add the following to your layout xml file to add an image:
<com.android.volley.toolbox.NetworkImageView
android:id="@+id/profile_picture"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
app:srcCompat="@android:drawable/spinner_background"/>
UserViewDialog.java
Add the following code to the onCreate method (Fragment, Activity) or the constructor (Dialog):
NetworkImageView profilePicture = view.findViewById(R.id.profile_picture);
profilePicture.setImageUrl("http://example.com/users/images/profile.jpg", ImageFetch.getImageLoader(getContext());
Picasso
Another excellent library from Square. Please see the site for some great examples: http://square.github.io/picasso/
this should be the better answer than the original one as it simplifies the implementation of networking on android in the present world 2017, and most of the real world application uses very good libraries like these.
– Rakibul Haq
Nov 28 '17 at 11:46
add a comment |
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:
http://api.example.com/stocks //ResponseWrapper<String> object containing a list of Srings with ticker symbols
http://api.example.com/stocks/$symbol //Stock object
http://api.example.com/stocks/$symbol/prices //PriceHistory<Stock> object
http://api.example.com/currencies //ResponseWrapper<String> object containing a list of currency abbreviation
http://api.example.com/currencies/$currency //Currency object
http://api.example.com/currencies/$id1/values/$id2 //PriceHistory<Currency> object comparing the prices of the first currency (id1) to the second (id2)
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:
implementation 'com.squareup.retrofit2:retrofit:2.3.0' //retrofit library, current as of September 21, 2017
implementation 'com.squareup.retrofit2:converter-gson:2.3.0' //gson serialization and deserialization support for retrofit, version must match retrofit version
FinancesApi.java
public interface FinancesApi {
@GET("stocks")
Call<ResponseWrapper<String>> listStocks();
@GET("stocks/{symbol}")
Call<Stock> getStock(@Path("symbol")String tickerSymbol);
@GET("stocks/{symbol}/prices")
Call<PriceHistory<Stock>> getPriceHistory(@Path("symbol")String tickerSymbol);
@GET("currencies")
Call<ResponseWrapper<String>> listCurrencies();
@GET("currencies/{symbol}")
Call<Currency> getCurrency(@Path("symbol")String currencySymbol);
@GET("currencies/{symbol}/values/{compare_symbol}")
Call<PriceHistory<Currency>> getComparativeHistory(@Path("symbol")String currency, @Path("compare_symbol")String currencyToPriceAgainst);
}
FinancesApiBuilder
public class FinancesApiBuilder {
public static FinancesApi build(String baseUrl){
return new Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(FinancesApi.class);
}
}
FinancesFragment snippet
FinancesApi api = FinancesApiBuilder.build("http://api.example.com/"); //trailing '/' required for predictable behavior
api.getStock("INTC").enqueue(new Callback<Stock>(){
@Override
public void onResponse(Call<Stock> stockCall, Response<Stock> stockResponse){
Stock stock = stockCall.body();
//do something with the stock
}
@Override
public void onResponse(Call<Stock> stockCall, Throwable t){
//something bad happened
}
}
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:
implementation 'com.android.volley:volley:1.0.0'
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:
public class ImageFetch {
private static ImageLoader imageLoader = null;
private static RequestQueue imageQueue = null;
public static ImageLoader getImageLoader(Context ctx){
if(imageLoader == null){
if(imageQueue == null){
imageQueue = Volley.newRequestQueue(ctx.getApplicationContext());
}
imageLoader = new ImageLoader(imageQueue, new ImageLoader.ImageCache() {
Map<String, Bitmap> cache = new HashMap<String, Bitmap>();
@Override
public Bitmap getBitmap(String url) {
return cache.get(url);
}
@Override
public void putBitmap(String url, Bitmap bitmap) {
cache.put(url, bitmap);
}
});
}
return imageLoader;
}
}
user_view_dialog.xml
Add the following to your layout xml file to add an image:
<com.android.volley.toolbox.NetworkImageView
android:id="@+id/profile_picture"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
app:srcCompat="@android:drawable/spinner_background"/>
UserViewDialog.java
Add the following code to the onCreate method (Fragment, Activity) or the constructor (Dialog):
NetworkImageView profilePicture = view.findViewById(R.id.profile_picture);
profilePicture.setImageUrl("http://example.com/users/images/profile.jpg", ImageFetch.getImageLoader(getContext());
Picasso
Another excellent library from Square. Please see the site for some great examples: http://square.github.io/picasso/
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:
http://api.example.com/stocks //ResponseWrapper<String> object containing a list of Srings with ticker symbols
http://api.example.com/stocks/$symbol //Stock object
http://api.example.com/stocks/$symbol/prices //PriceHistory<Stock> object
http://api.example.com/currencies //ResponseWrapper<String> object containing a list of currency abbreviation
http://api.example.com/currencies/$currency //Currency object
http://api.example.com/currencies/$id1/values/$id2 //PriceHistory<Currency> object comparing the prices of the first currency (id1) to the second (id2)
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:
implementation 'com.squareup.retrofit2:retrofit:2.3.0' //retrofit library, current as of September 21, 2017
implementation 'com.squareup.retrofit2:converter-gson:2.3.0' //gson serialization and deserialization support for retrofit, version must match retrofit version
FinancesApi.java
public interface FinancesApi {
@GET("stocks")
Call<ResponseWrapper<String>> listStocks();
@GET("stocks/{symbol}")
Call<Stock> getStock(@Path("symbol")String tickerSymbol);
@GET("stocks/{symbol}/prices")
Call<PriceHistory<Stock>> getPriceHistory(@Path("symbol")String tickerSymbol);
@GET("currencies")
Call<ResponseWrapper<String>> listCurrencies();
@GET("currencies/{symbol}")
Call<Currency> getCurrency(@Path("symbol")String currencySymbol);
@GET("currencies/{symbol}/values/{compare_symbol}")
Call<PriceHistory<Currency>> getComparativeHistory(@Path("symbol")String currency, @Path("compare_symbol")String currencyToPriceAgainst);
}
FinancesApiBuilder
public class FinancesApiBuilder {
public static FinancesApi build(String baseUrl){
return new Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(FinancesApi.class);
}
}
FinancesFragment snippet
FinancesApi api = FinancesApiBuilder.build("http://api.example.com/"); //trailing '/' required for predictable behavior
api.getStock("INTC").enqueue(new Callback<Stock>(){
@Override
public void onResponse(Call<Stock> stockCall, Response<Stock> stockResponse){
Stock stock = stockCall.body();
//do something with the stock
}
@Override
public void onResponse(Call<Stock> stockCall, Throwable t){
//something bad happened
}
}
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:
implementation 'com.android.volley:volley:1.0.0'
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:
public class ImageFetch {
private static ImageLoader imageLoader = null;
private static RequestQueue imageQueue = null;
public static ImageLoader getImageLoader(Context ctx){
if(imageLoader == null){
if(imageQueue == null){
imageQueue = Volley.newRequestQueue(ctx.getApplicationContext());
}
imageLoader = new ImageLoader(imageQueue, new ImageLoader.ImageCache() {
Map<String, Bitmap> cache = new HashMap<String, Bitmap>();
@Override
public Bitmap getBitmap(String url) {
return cache.get(url);
}
@Override
public void putBitmap(String url, Bitmap bitmap) {
cache.put(url, bitmap);
}
});
}
return imageLoader;
}
}
user_view_dialog.xml
Add the following to your layout xml file to add an image:
<com.android.volley.toolbox.NetworkImageView
android:id="@+id/profile_picture"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
app:srcCompat="@android:drawable/spinner_background"/>
UserViewDialog.java
Add the following code to the onCreate method (Fragment, Activity) or the constructor (Dialog):
NetworkImageView profilePicture = view.findViewById(R.id.profile_picture);
profilePicture.setImageUrl("http://example.com/users/images/profile.jpg", ImageFetch.getImageLoader(getContext());
Picasso
Another excellent library from Square. Please see the site for some great examples: http://square.github.io/picasso/
edited Mar 17 '18 at 8:26


kiamlaluno
19.1k146279
19.1k146279
answered Oct 20 '17 at 23:50
KG6ZVPKG6ZVP
1,29731635
1,29731635
this should be the better answer than the original one as it simplifies the implementation of networking on android in the present world 2017, and most of the real world application uses very good libraries like these.
– Rakibul Haq
Nov 28 '17 at 11:46
add a comment |
this should be the better answer than the original one as it simplifies the implementation of networking on android in the present world 2017, and most of the real world application uses very good libraries like these.
– Rakibul Haq
Nov 28 '17 at 11:46
this should be the better answer than the original one as it simplifies the implementation of networking on android in the present world 2017, and most of the real world application uses very good libraries like these.
– Rakibul Haq
Nov 28 '17 at 11:46
this should be the better answer than the original one as it simplifies the implementation of networking on android in the present world 2017, and most of the real world application uses very good libraries like these.
– Rakibul Haq
Nov 28 '17 at 11:46
add a comment |
Although above there is a huge solution pool, no one mentioned com.koushikdutta.ion
: https://github.com/koush/ion
It's also asynchronous and very simple to use:
Ion.with(context)
.load("http://example.com/thing.json")
.asJsonObject()
.setCallback(new FutureCallback<JsonObject>() {
@Override
public void onCompleted(Exception e, JsonObject result) {
// do stuff with the result or error
}
});
add a comment |
Although above there is a huge solution pool, no one mentioned com.koushikdutta.ion
: https://github.com/koush/ion
It's also asynchronous and very simple to use:
Ion.with(context)
.load("http://example.com/thing.json")
.asJsonObject()
.setCallback(new FutureCallback<JsonObject>() {
@Override
public void onCompleted(Exception e, JsonObject result) {
// do stuff with the result or error
}
});
add a comment |
Although above there is a huge solution pool, no one mentioned com.koushikdutta.ion
: https://github.com/koush/ion
It's also asynchronous and very simple to use:
Ion.with(context)
.load("http://example.com/thing.json")
.asJsonObject()
.setCallback(new FutureCallback<JsonObject>() {
@Override
public void onCompleted(Exception e, JsonObject result) {
// do stuff with the result or error
}
});
Although above there is a huge solution pool, no one mentioned com.koushikdutta.ion
: https://github.com/koush/ion
It's also asynchronous and very simple to use:
Ion.with(context)
.load("http://example.com/thing.json")
.asJsonObject()
.setCallback(new FutureCallback<JsonObject>() {
@Override
public void onCompleted(Exception e, JsonObject result) {
// do stuff with the result or error
}
});
answered Feb 17 '15 at 10:31
msysmilumsysmilu
1,6101617
1,6101617
add a comment |
add a comment |
New Thread
and AsyncTask solutions have been explained already.
AsyncTask
should ideally be used for short operations. Normal Thread
is not preferable for Android.
Have a look at alternate solution using HandlerThread and Handler
HandlerThread
Handy class for starting a new thread that has a looper. The looper can then be used to create handler classes. Note that
start()
must still be called.
Handler:
A Handler allows you to send and process Message and Runnable objects associated with a thread's MessageQueue. Each Handler instance is associated with a single thread and that thread's message queue. When you create a new Handler, it is bound to the thread / message queue of the thread that is creating it -- from that point on, it will deliver messages and runnables to that message queue and execute them as they come out of the message queue.
Solution:
Create
HandlerThread
Call
start()
onHandlerThread
Create
Handler
by gettingLooper
fromHanlerThread
Embed your Network operation related code in
Runnable
objectSubmit
Runnable
task toHandler
Sample code snippet, which address NetworkOnMainThreadException
HandlerThread handlerThread = new HandlerThread("URLConnection");
handlerThread.start();
handler mainHandler = new Handler(handlerThread.getLooper());
Runnable myRunnable = new Runnable() {
@Override
public void run() {
try {
Log.d("Ravi", "Before IO call");
URL page = new URL("http://www.google.com");
StringBuffer text = new StringBuffer();
HttpURLConnection conn = (HttpURLConnection) page.openConnection();
conn.connect();
InputStreamReader in = new InputStreamReader((InputStream) conn.getContent());
BufferedReader buff = new BufferedReader(in);
String line;
while ( (line = buff.readLine()) != null) {
text.append(line + "n");
}
Log.d("Ravi", "After IO call");
Log.d("Ravi",text.toString());
}catch( Exception err){
err.printStackTrace();
}
}
};
mainHandler.post(myRunnable);
Pros of using this approach:
- Creating new
Thread/AsyncTask
for each network operation is expensive. TheThread/AsyncTask
will be destroyed and re-created for next Network operations. But withHandler
andHandlerThread
approach, you can submit many network operations (as Runnable tasks) to singleHandlerThread
by usingHandler
.
This shall be the correct answer.
– Thecave3
2 days ago
add a comment |
New Thread
and AsyncTask solutions have been explained already.
AsyncTask
should ideally be used for short operations. Normal Thread
is not preferable for Android.
Have a look at alternate solution using HandlerThread and Handler
HandlerThread
Handy class for starting a new thread that has a looper. The looper can then be used to create handler classes. Note that
start()
must still be called.
Handler:
A Handler allows you to send and process Message and Runnable objects associated with a thread's MessageQueue. Each Handler instance is associated with a single thread and that thread's message queue. When you create a new Handler, it is bound to the thread / message queue of the thread that is creating it -- from that point on, it will deliver messages and runnables to that message queue and execute them as they come out of the message queue.
Solution:
Create
HandlerThread
Call
start()
onHandlerThread
Create
Handler
by gettingLooper
fromHanlerThread
Embed your Network operation related code in
Runnable
objectSubmit
Runnable
task toHandler
Sample code snippet, which address NetworkOnMainThreadException
HandlerThread handlerThread = new HandlerThread("URLConnection");
handlerThread.start();
handler mainHandler = new Handler(handlerThread.getLooper());
Runnable myRunnable = new Runnable() {
@Override
public void run() {
try {
Log.d("Ravi", "Before IO call");
URL page = new URL("http://www.google.com");
StringBuffer text = new StringBuffer();
HttpURLConnection conn = (HttpURLConnection) page.openConnection();
conn.connect();
InputStreamReader in = new InputStreamReader((InputStream) conn.getContent());
BufferedReader buff = new BufferedReader(in);
String line;
while ( (line = buff.readLine()) != null) {
text.append(line + "n");
}
Log.d("Ravi", "After IO call");
Log.d("Ravi",text.toString());
}catch( Exception err){
err.printStackTrace();
}
}
};
mainHandler.post(myRunnable);
Pros of using this approach:
- Creating new
Thread/AsyncTask
for each network operation is expensive. TheThread/AsyncTask
will be destroyed and re-created for next Network operations. But withHandler
andHandlerThread
approach, you can submit many network operations (as Runnable tasks) to singleHandlerThread
by usingHandler
.
This shall be the correct answer.
– Thecave3
2 days ago
add a comment |
New Thread
and AsyncTask solutions have been explained already.
AsyncTask
should ideally be used for short operations. Normal Thread
is not preferable for Android.
Have a look at alternate solution using HandlerThread and Handler
HandlerThread
Handy class for starting a new thread that has a looper. The looper can then be used to create handler classes. Note that
start()
must still be called.
Handler:
A Handler allows you to send and process Message and Runnable objects associated with a thread's MessageQueue. Each Handler instance is associated with a single thread and that thread's message queue. When you create a new Handler, it is bound to the thread / message queue of the thread that is creating it -- from that point on, it will deliver messages and runnables to that message queue and execute them as they come out of the message queue.
Solution:
Create
HandlerThread
Call
start()
onHandlerThread
Create
Handler
by gettingLooper
fromHanlerThread
Embed your Network operation related code in
Runnable
objectSubmit
Runnable
task toHandler
Sample code snippet, which address NetworkOnMainThreadException
HandlerThread handlerThread = new HandlerThread("URLConnection");
handlerThread.start();
handler mainHandler = new Handler(handlerThread.getLooper());
Runnable myRunnable = new Runnable() {
@Override
public void run() {
try {
Log.d("Ravi", "Before IO call");
URL page = new URL("http://www.google.com");
StringBuffer text = new StringBuffer();
HttpURLConnection conn = (HttpURLConnection) page.openConnection();
conn.connect();
InputStreamReader in = new InputStreamReader((InputStream) conn.getContent());
BufferedReader buff = new BufferedReader(in);
String line;
while ( (line = buff.readLine()) != null) {
text.append(line + "n");
}
Log.d("Ravi", "After IO call");
Log.d("Ravi",text.toString());
}catch( Exception err){
err.printStackTrace();
}
}
};
mainHandler.post(myRunnable);
Pros of using this approach:
- Creating new
Thread/AsyncTask
for each network operation is expensive. TheThread/AsyncTask
will be destroyed and re-created for next Network operations. But withHandler
andHandlerThread
approach, you can submit many network operations (as Runnable tasks) to singleHandlerThread
by usingHandler
.
New Thread
and AsyncTask solutions have been explained already.
AsyncTask
should ideally be used for short operations. Normal Thread
is not preferable for Android.
Have a look at alternate solution using HandlerThread and Handler
HandlerThread
Handy class for starting a new thread that has a looper. The looper can then be used to create handler classes. Note that
start()
must still be called.
Handler:
A Handler allows you to send and process Message and Runnable objects associated with a thread's MessageQueue. Each Handler instance is associated with a single thread and that thread's message queue. When you create a new Handler, it is bound to the thread / message queue of the thread that is creating it -- from that point on, it will deliver messages and runnables to that message queue and execute them as they come out of the message queue.
Solution:
Create
HandlerThread
Call
start()
onHandlerThread
Create
Handler
by gettingLooper
fromHanlerThread
Embed your Network operation related code in
Runnable
objectSubmit
Runnable
task toHandler
Sample code snippet, which address NetworkOnMainThreadException
HandlerThread handlerThread = new HandlerThread("URLConnection");
handlerThread.start();
handler mainHandler = new Handler(handlerThread.getLooper());
Runnable myRunnable = new Runnable() {
@Override
public void run() {
try {
Log.d("Ravi", "Before IO call");
URL page = new URL("http://www.google.com");
StringBuffer text = new StringBuffer();
HttpURLConnection conn = (HttpURLConnection) page.openConnection();
conn.connect();
InputStreamReader in = new InputStreamReader((InputStream) conn.getContent());
BufferedReader buff = new BufferedReader(in);
String line;
while ( (line = buff.readLine()) != null) {
text.append(line + "n");
}
Log.d("Ravi", "After IO call");
Log.d("Ravi",text.toString());
}catch( Exception err){
err.printStackTrace();
}
}
};
mainHandler.post(myRunnable);
Pros of using this approach:
- Creating new
Thread/AsyncTask
for each network operation is expensive. TheThread/AsyncTask
will be destroyed and re-created for next Network operations. But withHandler
andHandlerThread
approach, you can submit many network operations (as Runnable tasks) to singleHandlerThread
by usingHandler
.
edited Nov 5 '17 at 4:41
answered May 5 '17 at 20:11


Ravindra babuRavindra babu
29.4k5157135
29.4k5157135
This shall be the correct answer.
– Thecave3
2 days ago
add a comment |
This shall be the correct answer.
– Thecave3
2 days ago
This shall be the correct answer.
– Thecave3
2 days ago
This shall be the correct answer.
– Thecave3
2 days ago
add a comment |
This works. Just made Dr.Luiji's answer a little simpler.
new Thread() {
@Override
public void run() {
try {
//Your code goes here
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
add a comment |
This works. Just made Dr.Luiji's answer a little simpler.
new Thread() {
@Override
public void run() {
try {
//Your code goes here
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
add a comment |
This works. Just made Dr.Luiji's answer a little simpler.
new Thread() {
@Override
public void run() {
try {
//Your code goes here
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
This works. Just made Dr.Luiji's answer a little simpler.
new Thread() {
@Override
public void run() {
try {
//Your code goes here
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
answered Feb 13 '15 at 23:10


KacyKacy
1,50022032
1,50022032
add a comment |
add a comment |
On Android, network operations cannot be run on the main thread. You can use Thread, AsyncTask (short-running tasks), Service (long-running tasks) to do network operations.
add a comment |
On Android, network operations cannot be run on the main thread. You can use Thread, AsyncTask (short-running tasks), Service (long-running tasks) to do network operations.
add a comment |
On Android, network operations cannot be run on the main thread. You can use Thread, AsyncTask (short-running tasks), Service (long-running tasks) to do network operations.
On Android, network operations cannot be run on the main thread. You can use Thread, AsyncTask (short-running tasks), Service (long-running tasks) to do network operations.
edited Jun 25 '16 at 9:32


Peter Mortensen
13.5k1984111
13.5k1984111
answered Jun 25 '15 at 7:42


Ponsuyambu VelladuraiPonsuyambu Velladurai
1,05411331
1,05411331
add a comment |
add a comment |
Accessing network resources from the main (UI) thread cause this exception. Use a separate thread or AsyncTask for accessing a network resource to avoid this problem.
add a comment |
Accessing network resources from the main (UI) thread cause this exception. Use a separate thread or AsyncTask for accessing a network resource to avoid this problem.
add a comment |
Accessing network resources from the main (UI) thread cause this exception. Use a separate thread or AsyncTask for accessing a network resource to avoid this problem.
Accessing network resources from the main (UI) thread cause this exception. Use a separate thread or AsyncTask for accessing a network resource to avoid this problem.
edited Jun 25 '16 at 9:35


Peter Mortensen
13.5k1984111
13.5k1984111
answered Aug 13 '15 at 8:26


RevanthKrishnaKumar V.RevanthKrishnaKumar V.
1,48411530
1,48411530
add a comment |
add a comment |
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.
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);
}
});
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
add a comment |
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.
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);
}
});
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
add a comment |
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.
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);
}
});
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
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.
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);
}
});
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
edited Oct 10 '17 at 7:52


Ravindra babu
29.4k5157135
29.4k5157135
answered Jun 9 '17 at 5:57
Shinoo GoyalShinoo Goyal
45656
45656
add a comment |
add a comment |
You are not allowed to implement network operations on the UI thread on Android. You will have to use AsyncTask class to perform network related operations like sending API request, downloading image from a URL, etc. and using callback methods of AsyncTask, you can get you result in onPostExecute menthod and you will be in the UI thread and you can populate UI with data from web service or something like that.
Example: Suppose you want to download image from an URL: https://www.samplewebsite.com/sampleimage.jpg
Solution using AsyncTask:
are respectively.
public class MyDownloader extends AsyncTask<String,Void,Bitmap>
{
@Override
protected void onPreExecute() {
// Show progress dialog
super.onPreExecute();
}
@Override
protected void onPostExecute(Bitmap bitmap) {
//Populate Ui
super.onPostExecute(bitmap);
}
@Override
protected Bitmap doInBackground(String... params) {
// Open URL connection read bitmaps and return form here
return result;
}
@Override
protected void onProgressUpdate(Void... values) {
// Show progress update
super.onProgressUpdate(values);
}
}
}
Note: Do not forget to add the Internet permission in the Android manifest file. It will work like a charm. :)
add a comment |
You are not allowed to implement network operations on the UI thread on Android. You will have to use AsyncTask class to perform network related operations like sending API request, downloading image from a URL, etc. and using callback methods of AsyncTask, you can get you result in onPostExecute menthod and you will be in the UI thread and you can populate UI with data from web service or something like that.
Example: Suppose you want to download image from an URL: https://www.samplewebsite.com/sampleimage.jpg
Solution using AsyncTask:
are respectively.
public class MyDownloader extends AsyncTask<String,Void,Bitmap>
{
@Override
protected void onPreExecute() {
// Show progress dialog
super.onPreExecute();
}
@Override
protected void onPostExecute(Bitmap bitmap) {
//Populate Ui
super.onPostExecute(bitmap);
}
@Override
protected Bitmap doInBackground(String... params) {
// Open URL connection read bitmaps and return form here
return result;
}
@Override
protected void onProgressUpdate(Void... values) {
// Show progress update
super.onProgressUpdate(values);
}
}
}
Note: Do not forget to add the Internet permission in the Android manifest file. It will work like a charm. :)
add a comment |
You are not allowed to implement network operations on the UI thread on Android. You will have to use AsyncTask class to perform network related operations like sending API request, downloading image from a URL, etc. and using callback methods of AsyncTask, you can get you result in onPostExecute menthod and you will be in the UI thread and you can populate UI with data from web service or something like that.
Example: Suppose you want to download image from an URL: https://www.samplewebsite.com/sampleimage.jpg
Solution using AsyncTask:
are respectively.
public class MyDownloader extends AsyncTask<String,Void,Bitmap>
{
@Override
protected void onPreExecute() {
// Show progress dialog
super.onPreExecute();
}
@Override
protected void onPostExecute(Bitmap bitmap) {
//Populate Ui
super.onPostExecute(bitmap);
}
@Override
protected Bitmap doInBackground(String... params) {
// Open URL connection read bitmaps and return form here
return result;
}
@Override
protected void onProgressUpdate(Void... values) {
// Show progress update
super.onProgressUpdate(values);
}
}
}
Note: Do not forget to add the Internet permission in the Android manifest file. It will work like a charm. :)
You are not allowed to implement network operations on the UI thread on Android. You will have to use AsyncTask class to perform network related operations like sending API request, downloading image from a URL, etc. and using callback methods of AsyncTask, you can get you result in onPostExecute menthod and you will be in the UI thread and you can populate UI with data from web service or something like that.
Example: Suppose you want to download image from an URL: https://www.samplewebsite.com/sampleimage.jpg
Solution using AsyncTask:
are respectively.
public class MyDownloader extends AsyncTask<String,Void,Bitmap>
{
@Override
protected void onPreExecute() {
// Show progress dialog
super.onPreExecute();
}
@Override
protected void onPostExecute(Bitmap bitmap) {
//Populate Ui
super.onPostExecute(bitmap);
}
@Override
protected Bitmap doInBackground(String... params) {
// Open URL connection read bitmaps and return form here
return result;
}
@Override
protected void onProgressUpdate(Void... values) {
// Show progress update
super.onProgressUpdate(values);
}
}
}
Note: Do not forget to add the Internet permission in the Android manifest file. It will work like a charm. :)
edited Jun 25 '16 at 9:39


Peter Mortensen
13.5k1984111
13.5k1984111
answered Dec 18 '15 at 9:23


KrishnaKrishna
1,8401120
1,8401120
add a comment |
add a comment |
There is another very convenient way for tackling this issue - use rxJava's concurrency capabilities. You can execute any task in background and post results to main thread in a very convenient way, so these results will be handed to processing chain.
The first verified answer advice is to use AsynTask. Yes, this is a solution, but it is obsolete nowadays, because there are new tools around.
String getUrl() {
return "SomeUrl";
}
private Object makeCallParseResponse(String url) {
return null;
//
}
private void processResponse(Object o) {
}
The getUrl method provides the URL address, and it will be executed on the main thread.
makeCallParseResponse(..) - does actual work
processResponse(..) - will handle result on main thread.
The code for asynchronous execution will look like:
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
}
});
Compared to AsyncTask, this method allow to switch schedulers an arbitrary number of times (say, fetch data on one scheduler and process those data on another (say, Scheduler.computation()). You can also define you own schedulers.
In order to use this library, include following lines into you build.gradle file:
compile 'io.reactivex:rxjava:1.1.5'
compile 'io.reactivex:rxandroid:1.2.0'
The last dependency includes support for the .mainThread() scheduler.
There is an excellent ebook for rx-java.
quite an extensive approach it would to be schedule by our own and i don't know why we should if it is already being an option on Android side?
– Prakhar1001
Sep 15 '16 at 14:10
add a comment |
There is another very convenient way for tackling this issue - use rxJava's concurrency capabilities. You can execute any task in background and post results to main thread in a very convenient way, so these results will be handed to processing chain.
The first verified answer advice is to use AsynTask. Yes, this is a solution, but it is obsolete nowadays, because there are new tools around.
String getUrl() {
return "SomeUrl";
}
private Object makeCallParseResponse(String url) {
return null;
//
}
private void processResponse(Object o) {
}
The getUrl method provides the URL address, and it will be executed on the main thread.
makeCallParseResponse(..) - does actual work
processResponse(..) - will handle result on main thread.
The code for asynchronous execution will look like:
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
}
});
Compared to AsyncTask, this method allow to switch schedulers an arbitrary number of times (say, fetch data on one scheduler and process those data on another (say, Scheduler.computation()). You can also define you own schedulers.
In order to use this library, include following lines into you build.gradle file:
compile 'io.reactivex:rxjava:1.1.5'
compile 'io.reactivex:rxandroid:1.2.0'
The last dependency includes support for the .mainThread() scheduler.
There is an excellent ebook for rx-java.
quite an extensive approach it would to be schedule by our own and i don't know why we should if it is already being an option on Android side?
– Prakhar1001
Sep 15 '16 at 14:10
add a comment |
There is another very convenient way for tackling this issue - use rxJava's concurrency capabilities. You can execute any task in background and post results to main thread in a very convenient way, so these results will be handed to processing chain.
The first verified answer advice is to use AsynTask. Yes, this is a solution, but it is obsolete nowadays, because there are new tools around.
String getUrl() {
return "SomeUrl";
}
private Object makeCallParseResponse(String url) {
return null;
//
}
private void processResponse(Object o) {
}
The getUrl method provides the URL address, and it will be executed on the main thread.
makeCallParseResponse(..) - does actual work
processResponse(..) - will handle result on main thread.
The code for asynchronous execution will look like:
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
}
});
Compared to AsyncTask, this method allow to switch schedulers an arbitrary number of times (say, fetch data on one scheduler and process those data on another (say, Scheduler.computation()). You can also define you own schedulers.
In order to use this library, include following lines into you build.gradle file:
compile 'io.reactivex:rxjava:1.1.5'
compile 'io.reactivex:rxandroid:1.2.0'
The last dependency includes support for the .mainThread() scheduler.
There is an excellent ebook for rx-java.
There is another very convenient way for tackling this issue - use rxJava's concurrency capabilities. You can execute any task in background and post results to main thread in a very convenient way, so these results will be handed to processing chain.
The first verified answer advice is to use AsynTask. Yes, this is a solution, but it is obsolete nowadays, because there are new tools around.
String getUrl() {
return "SomeUrl";
}
private Object makeCallParseResponse(String url) {
return null;
//
}
private void processResponse(Object o) {
}
The getUrl method provides the URL address, and it will be executed on the main thread.
makeCallParseResponse(..) - does actual work
processResponse(..) - will handle result on main thread.
The code for asynchronous execution will look like:
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
}
});
Compared to AsyncTask, this method allow to switch schedulers an arbitrary number of times (say, fetch data on one scheduler and process those data on another (say, Scheduler.computation()). You can also define you own schedulers.
In order to use this library, include following lines into you build.gradle file:
compile 'io.reactivex:rxjava:1.1.5'
compile 'io.reactivex:rxandroid:1.2.0'
The last dependency includes support for the .mainThread() scheduler.
There is an excellent ebook for rx-java.
edited Jun 25 '16 at 9:48


Peter Mortensen
13.5k1984111
13.5k1984111
answered Jun 23 '16 at 22:00
Alex ShutovAlex Shutov
2,7062610
2,7062610
quite an extensive approach it would to be schedule by our own and i don't know why we should if it is already being an option on Android side?
– Prakhar1001
Sep 15 '16 at 14:10
add a comment |
quite an extensive approach it would to be schedule by our own and i don't know why we should if it is already being an option on Android side?
– Prakhar1001
Sep 15 '16 at 14:10
quite an extensive approach it would to be schedule by our own and i don't know why we should if it is already being an option on Android side?
– Prakhar1001
Sep 15 '16 at 14:10
quite an extensive approach it would to be schedule by our own and i don't know why we should if it is already being an option on Android side?
– Prakhar1001
Sep 15 '16 at 14:10
add a comment |
1 2
next
protected by Jorgesys Jan 28 '14 at 18:29
Thank you for your interest in this question.
Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).
Would you like to answer one of these unanswered questions instead?
122
Read this blog post on the NetworkOnMainThreadException for more information. It explains why this occurs on Android 3.0 and above.
– Adrian Monk
Aug 7 '12 at 12:38
4
To be on rite track first read about the Network Requests in android then i would recommend to study "Volley".
– Anuj Sharma
Jan 23 '14 at 6:39
2
There are many alternative libraries that solve this issue. Many are listed at the bottom of this page. If you got more, we take them :)
– Snicolas
Feb 11 '14 at 22:55
You need to run internet activities on a thread separate from main (UI) thread
– Naveed Ahmad
Oct 30 '14 at 20:44
stackoverflow.com/questions/16439587/… above link is good
– nguyenvangiangbn
Jan 1 '15 at 5:12