HTTP Response in Android - NetworkOnMainThreadException [duplicate] - android

This question already has answers here:
How can I fix 'android.os.NetworkOnMainThreadException'?
(66 answers)
Closed 9 years ago.
I want to check the HTTP response of a certain URL before loading into a webview. I only want to load webview if http response code is 200. This is a workaround for intercepting http errors. I have below:
HttpGet httpRequest = new HttpGet( "http://example.com");
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response = httpclient.execute(httpRequest);
int code = response.getStatusLine().getStatusCode();
But I encountered the following error:
java.lang.RuntimeException: Unable to start activity ComponentInfo
android.os.NetworkOnMainThreadException
How to fix it? Or any workaround to interept http errors in webview? Thanks

android.os.NetworkOnMainThreadException occurs whenever you try to make long running tasks/process on Main UI Thread directly.
To resolve this issue, cover your webservice call inside AsyncTask. FYI, AsyncTask in android known as Painless Threading which means developer don't need to bother about Thread management. So Go and implement web API call or any long running tasks using AsyncTask, there are plenty of examples available on the web.
Update:
I only want to load webview if http response code is 200.
=> Based on your requirement, I would say include your code inside doInBackground() method and return status code value, Which you can check inside onPostExecute(). Now here you are getting status code value 200/201 then you can load WebView.

class HTTPRequest extends AsyncTask<int, Void, void> {
protected int doInBackground() {
try {
HttpGet httpRequest = new HttpGet( "http://example.com");
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response = httpclient.execute(httpRequest);
int code = response.getStatusLine().getStatusCode();
return code;
} catch (Exception e) {
e.printstacktrace();
}
}
protected void onPostExecute(int code) {
// TODO: check this.exception
// retrieve your 'code' here
}
}

You are getting this Exception because you are carrying out a heavy Computation i.e Acessing Network in your case on UI Thread.
You should never do this .
Rather you can move this code to background Java Thread :
Try :
private void doNetworkCompuation()
{
new Thread(new Runnable() {
#Override
public void run() {
HttpGet httpRequest = new HttpGet( "http://example.com");
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response = httpclient.execute(httpRequest);
int code = response.getStatusLine().getStatusCode();
}).start();
}

Try executing this code in Async Thread.
You can have a refrence from here:
How to fix android.os.NetworkOnMainThreadException?

You are not allowed to execute network requests on the main thread. You have to use a different thread for making this requests. You should use the AsyncTask, for an example look here.

Related

Unable to connect with internet

Hi I'm trying to connect with internet with this code:
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://192.168.0.100/webnet/xyz.php");
String result = null;
InputStream is = null;
StringBuilder sb = null;
HttpResponse response = httpclient.execute(httppost);
I registered Internet permission on manifest file
I got this error:
System.err android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1117)
I tests this app with API level 8
You can not run long running task on main thread. please move your network related task in background.
Refer this : AsyncTask Android example
Try this before executing this block of code. may works in some cases:
try {
Class strictModeClass=Class.forName("android.os.StrictMode");
Class strictModeThreadPolicyClass=Class.forName("android.os.StrictMode$ThreadPolicy");
Object laxPolicy = strictModeThreadPolicyClass.getField("LAX").get(null);
Method method_setThreadPolicy = strictModeClass.getMethod("setThreadPolicy",strictModeThreadPolicyClass );
method_setThreadPolicy.invoke(null,laxPolicy);
}
catch (Exception e) {
}
And Try this before asking questions here: "google.com" # agree with kevinDTimm
Anyway you SHOULD NOT call network on UI threads.
Since Android 3.0, you'll see this error when you're trying to make network requests from the main thread. Move this code to a separate thread.
You check first which ip-address is the on (IPV4/IPV6)

Android SDK http request get process percentage

How can I get the process percentage of a HTTP request?
I've got this code for the request:
HttpClient requestclient = new DefaultHttpClient();
HttpResponse requestresponse = requestclient.execute(new HttpGet("example.com"));
StatusLine requeststatus = requestresponse.getStatusLine();
if(requeststatus.getStatusCode() == HttpStatus.SC_OK){
ByteArrayOutputStream requestoutput = new ByteArrayOutputStream();
requestresponse.getEntity().writeTo(requestoutput);
requestoutput.close();
String requestresult = requestoutput.toString();
return requestresult;
} else{.
requestresponse.getEntity().getContent().close();
throw new IOException(requeststatus.getReasonPhrase());
}
Thanks!
HTTP requests should be run either in an IntentService or AsyncTask. That is, always run them in the background.
AsyncTask has methods for displaying the percentage complete: publishProgress() from doInBackground(), and onProgressUpdate() in the main Activity.
An IntentService can show progress by broadcast Intents back to the Activity, or by running a progressBar, or (in JellyBean and later) by using a progress notification.

Can EntityUtils.toString() cause a NetworkOnMainThreadException?

I have a setup where I perform my http requests in the doInBackground() method of an AsyncTask as follows:
#Override
protected HttpResponse doInBackground(HttpRequestBase... httpRequests)
{
HttpResponse httpResponse = HttpClient.execute(HttpUriRequest);
return httpResponse;
}
This HttpResponse object is then passed on to the onPostExecute() method of my AsyncTask to be passed on to a handler (the original caller of the http request) and processed as necessary, as follows:
checking the response code using httpResponse.getStatusLine().getStatusCode();
getting the response content using EntityUtils.toString(httpResponse.getEntity())).
This setup has been working fine on phones running older versions of Android.
Running my app now on Ice Cream Sandwich (Galaxy Nexus) I find that the first few http requests in my app as above work fine but then there is this one http request which consistently throws an exception with a stack trace as follows (trimmed slightly for readability):
....
at org.apache.http.util.EntityUtils.toString(EntityUtils.java:139)
at java.io.InputStreamReader.close(InputStreamReader.java:145)
at org.apache.http.conn.EofSensorInputStream.close(EofSensorInputStream.java:213)
...
at libcore.io.BlockGuardOs.recvfrom(BlockGuardOs.java:151)
at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1084)
android.os.NetworkOnMainThreadException
I am confused. Does this then mean that the EntityUtils.toString(HttpEntity) method is a potential culprit for throwing the new (and ever so annoying) NetworkOnMainThreadException? If so, any advice on reworking my setup to make http requests in a separate thread such that the response can be processed on the main thread?
Please try the following: modify your doInBackground function to return the value of the HTTP response.
protected String doInBackground(HttpRequestBase... httpRequests)
{
HttpResponse httpResponse = HttpClient.execute(HttpUriRequest);
if (httpResponse.getEntity() != null) {
return EntityUtils.toString(httpResponse.getEntity());
}
return "";
}

it didn't work to connect the android app to servlet page to passing data

i want to connect my android app to my servlet site ,, that i need to pass some data from the app to the url
Can anyone help me?
I have written this code to pass two parameters but it generates an exception:
HttpPost postMethod = new HttpPost("http://androidsaveitem.appspot.com/view");
List<NameValuePair> formparams = new ArrayList<NameValuePair>();
formparams.add(new BasicNameValuePair("description+", "HAANAA"));
formparams.add(new BasicNameValuePair("id+", "11223"));
UrlEncodedFormEntity entity;
entity = new UrlEncodedFormEntity(formparams);
postMethod.setEntity(entity);
DefaultHttpClient hc = new DefaultHttpClient();
HttpResponse response = hc.execute(postMethod);
it seems that you are blocking the UI thread , and ANR Exception is raised since if your UI Thread is blocked for 5 second this exception will occur , to come over this issue you can use Thread or AsyncTask to do the job ,so your UI thread don't get blocked
example :
public myAsnyc extends AsyncTask<Void, Void,Void>{
protected void doInBackground(){
HttpPost postMethod = new HttpPost("http://androidsaveitem.appspot.com/view");
List<NameValuePair> formparams = new ArrayList<NameValuePair>();
formparams.add(new BasicNameValuePair("description+", "HAANAA"));
formparams.add(new BasicNameValuePair("id+", "11223"));
UrlEncodedFormEntity entity;
entity = new UrlEncodedFormEntity(formparams);
postMethod.setEntity(entity);
DefaultHttpClient hc = new DefaultHttpClient();
HttpResponse response = hc.execute(postMethod);
}
protected void onPostExecute(){
log.d("myApp", "success");
}
}
and if you want to execute it
make this call
new myAsnyc().execute();
if you want to update the UI elements use the onPostExecute() method and modify the generic type of the async task
UPDATE
execute the following code
use this code
try {
InetAddress i = InetAddress.getByName("http://androidsaveitem.appspot.com/view");
} catch (UnknownHostException e1) {
e1.printStackTrace();
}
before you call the async task
if the exception occur fine , re run the app second time it will run normally

Do POST request with Android DefaultHTTPClient cause freeze on execute()

I need post data to server.
I use this code:
HttpClient client = new DefaultHttpClient();
try {
HttpPost httppost = new HttpPost(serverUrl);
StringEntity se = new StringEntity(data);
httppost.setEntity(se);
httppost.setHeader("Accept", "application/json");
httppost.setHeader("Content-type", "application/json");
// Execute HTTP Post Request
HttpResponse response = client.execute(httppost);
int statusCode = response.getStatusLine().getStatusCode();
Log.i(TVProgram.TAG, "ErrorHandler post status code: " + statusCode);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (client != null) {
client.getConnectionManager().shutdown();
}
}
But problem is that Android freeze on execute() method, application is blocked out and after some time Android tell me that application doesn't respond.
I tried to debug into SDK classes and it freeze in AbstractSessionInputBuffer class on the line 103 which is
l = this.instream.read(this.buffer, off, len);
I also tried it run the request in separated thread, but the same problem.
I tested it on Android 2.1 (emulator) and Android 2.2 real mobile device.
I also tried to set HTTP proxy and use Fiddler to check HTTP communication data are received by server and server also send correct answer and HTTP code 200. All seems to be ok.
What is wrong please?
UPDATE: When I use AndroidHttpClient which is part of Android 2.2 SDK it works great. But it is not in earlier version of Android. So I include it's source code in my app for now. But AndroidHttpClient use DefaultHTTPClient internally, so problem will be in configuration of DefaultHttpClient.
I am using a POST HTTP request successfully. Here is my code. I removed pieces using handler to display messages etc. and the handler itself.
The POST string is like "&NAME=value#NAME2=value2"...
protected class ConnectingThread implements Runnable
{
Message msg;
private Handler mExtHandler;
private String mData;
private String mUrl;
/**
* #param h (Handler) - a handler for messages from this thread
* #param data (String) - data to be send in HTTP request's POST
* #param url (String) - URL to which to connect
*/
ConnectingThread(Handler h, String data, String url) {
mExtHandler = h;
mData = data;
mUrl = url;
}
public void run() {
try {
// TODO use the handler to display txt info about connection
URL url = new URL(mUrl);
URLConnection conn = url.openConnection();
conn.setConnectTimeout(CONN_TIMEOUT_MILLIS);
conn.setDoOutput(true);
BufferedOutputStream wr = new BufferedOutputStream(conn.getOutputStream());
wr.write(mData.getBytes());
wr.flush();
wr.close();
String sReturn = null;
BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
int length = conn.getContentLength();
char[] buffer = new char[length];
int read = rd.read(buffer);
if(read == length)
sReturn = new String(buffer);
rd.close();
buffer = null;
// TODO use the handler to use the response
} catch (Exception e) {
//....
}
// TODO use the handler to display txt info about connection ERROR
}
}
Isn't client.execute(httppost); synchronous ?
You probably need to put this in a thread, else it will freeze the UI.
Yes it is being freezed just becoz you haven't implemented this as Asynchronous process. Because while it makes web request, your UI will wait for the response and then it will be updated once the response is received.
So this should be implemented as Asynchronous process, and user should be notified (with progress bar or progress dialog) that there is something happening.
Now, Instead of implementing Runnable class, in android its preferrable and recommended to use AsyncTask, its also known as Painless Threading.
Do you background tasks inside the doInBackground() method.
Do your display type of operations inside onPostExecute() method, like updating listview with fetched data, display values inside TextViews....etc.
Display ProgressBar or ProgressDialog inside the onPreExecute() method.
Use AndroidHttpClient helped me in this situation.
But now complete AndroidHttpClient and DefaultHttpClient are obsolete in current version of Android so it is not important now.

Categories

Resources