I have some code below:
protected void testConnection(String url) {
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpGet httpget = new HttpGet(url);
ResponseHandler<String> responsehandler = new BasicResponseHandler();
try {
String connection = httpclient.execute(httpget, responsehandler);
Toast.makeText(getBaseContext(), R.string.connection_succeed, Toast.LENGTH_SHORT).show();
view_result.setText(connection);
} catch(IOException e) {
Toast.makeText(getBaseContext(), R.string.connection_failed, Toast.LENGTH_SHORT).show();
}
httpclient.getConnectionManager().shutdown();
}
and add a permission in Menifest:
<uses-permission android:name="android.permission.INTERNET"/>
But it goes an exception:
NetworkOnMainThreadException,
How can i do?
On ICS and later you cannot do network operations on the UI thread anymore. Instead you are forced to create a new thread and do your networking stuff there.
Possible tools are Android's AsyncTask and the normal Java Thread.
A good tutorial can be found here: Android Threads, Handlers and AsyncTask - Tutorial
Starting from API 11, you can not manipulate network (time-consuming) operations on main thread. Use AsyncTask or Thread to perform such operations.
You cant perform network operations in event thread, since android Api Level 11.
Instead you should do network operation in another thread than event thread, and use Handler or Asynctask to do so.
I you run your code in android 2.x and its lower version, i think this code will run perfectly. But if you run this in 3.x and it's upper version then you get an Exception. The problem is the you need to call the web service from your worker thread(AsyncTask<>) . You can not call the web service from the main thread.
Related
I need to make an api call on click of button. So i do it following way.
btn.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
try
{
HttpResponse apiResponse = mySingleTonehttpClient.execute(new HttpGet(Url));
HttpEntity resEntity = apiResponse.getEntity();
InputStream instream = resEntity.getContent();
String result = convertInputStreamToString(instream);
}
}
This code is working fine if i set targetSDKVersion = 8 in Manifest file. But giving me Network mainthread error for targetSDKVersion = 11. Can anyone suggest me what should i do?
Thanks,
Jay
The reason for this is that you're not supposed to do things that can possible take a long time in the UI Thread. Because doing that will result in the UI being blocked, and you're application will be lagging.
That's why you should either use a Worker Thread or an AsyncTask to do Network IO. You can read more information about how to use them and how they can interact with the UI Thread on the Android Developer guide.
You should not do networks call on main/UI thread of Application. you may start new worker thread that will run in separate thread rather than on UI thread.
I want to create an autoCompleteTextview with the suggestion from the web-service. On text change I call the web service with the text entered.
public String searchpalace_Searchtext(String serchtext)
{
String resultString = "";
try {
String searchtext = URLEncoder.encode(String.valueOf(serchtext), "UTF-8");
HttpClient Clientloc = new DefaultHttpClient();
String URL = baseUrl + "places?name=" + searchtext;
HttpGet httpget = new HttpGet(URL);
ResponseHandler<String> responseHandler = new BasicResponseHandler();
resultString = Clientloc.execute(httpget, responseHandler);
}
catch (Exception e) {
resultString = "";
}
return resultString;
}
This function is called from the asyncTask when reach character is entered or deleted. Now when the text is entered fast the I want to cancel the pending request when the new request is arrived. How can I cancel the previous request?
You can go through each queued task and call the cancel() method. Check if the task was cancelled using isCancelled(). Do not trigger async tasks for every change in the text box. You can introduce a small delay to avoid unnecessary creation of AsyncTask objects.
You can use Android volley network tool kid for cancel the HttpRequest,
If HttpClient.execute() can be interrupted, AsyncTask.cancel(true) will do it if you pass (true). The docs don't say if it's interruptable or not, experiment.
If it doesn't then you may need to investigate the toolkit suggested in another answer.
Anyway you can check isCancelled() and not apply the result. Probably not a huge overhead once the connection has been started.
Note that, depending on Android version, sometimes multiple AsyncTasks can run in parallel (donut - honecomb) and sometimes they only run one at a time and queue up (honeycomb onwards). You can change the thread executor to allow them to run in parallel, see the AsyncTask class docs, but this will affect the rest of your app too.
Also note you're not allowed to re-use an AsyncTask once it's been run.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Android HttpClient : NetworkOnMainThreadException
I have a php script on a server that recieves get requests, and mails out the content.
So lets say we have http://url.com/testmail.php?message=somemessage
the contents of "message" will be sent in an email.
I want my app to be able to call this script, and insert it's own mesage in the request. It will mostly be used for user feedback. I know it would be better to use POST, and if there is some android function that can natively handle mail, please enlighten me as I am new.
This is the code I have at the moment inside my main activities "onCreate", and it is generating exceptions:
HttpClient httpClient = new DefaultHttpClient();
String url = "http://someurl/testmail.php?message=eventualjavavariable";
HttpGet httpGet = new HttpGet(url);
try {
HttpResponse response = httpClient.execute(httpGet);
StatusLine statusLine = response.getStatusLine();
if (statusLine.getStatusCode() == HttpStatus.SC_OK) {
HttpEntity entity = response.getEntity();
ByteArrayOutputStream out = new ByteArrayOutputStream();
entity.writeTo(out);
out.close();
String responseStr = out.toString();
// do something with response
} else {
// handle bad response
}
} catch (ClientProtocolException e) {
// handle exception
} catch (IOException e) {
// handle exception
}
I also have added this line in my Android Manifest file:
<uses-permission android:name="android.permission.INTERNET"/>
What am I doing wrong?
This is my LogCat:
10-09 15:12:33.185: E/AndroidRuntime(5561): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.android.fragments/com.example.android.fragments.MainActivity}: android.os.NetworkOnMainThreadException
10-09 15:12:33.185: E/AndroidRuntime(5561): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2059)
10-09 15:12:33.185: E/AndroidRuntime(5561): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
10-09 15:12:33.185: E/AndroidRuntime(5561): at android.app.ActivityThread.access$600(ActivityThread.java:130)
10-09 15:12:33.185: E/AndroidRuntime(5561): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
The application is crashing due to network activity on the main UI thread, which itself is not a very good practice, as the application can stop responding and might get killed by the OS. You should always try to do your background processing in some separate thread, and not on the main UI thread.
You need to make the HttpConnection on a background thread, maybe by using an AsyncTask.
As the name of the exception indicates, you are not allowed to perform a networking operation on the main thread. See the reference documentation.
A NetworkOnMainThreadException is thrown when an application attempts to perform a networking operation on its main thread. 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, but it's heavily discouraged.
Some examples of other operations that ICS and HoneyComb won't allow you to perform on the UI thread are:
Opening a Socket connection (i.e. new Socket()).
HTTP requests (i.e. HTTPClient and HTTPUrlConnection).
Attempting to connect to a remote MySQL database.
Downloading a file (i.e. Downloader.downloadFile()).
If you are attempting to perform any of these operations on the UI thread, you must wrap them in a worker thread. The easiest way to do this is to use of an AsyncTask, which allows you to perform asynchronous work on your user interface. An AsyncTask will perform the blocking operations in a worker thread and will publish the results on the UI thread, without requiring you to handle threads and/or handlers yourself.
I'm trying to post data to URL by using Android App.
URL:
parameters:
"name" and "message"
I use the following code but it doesn't work:
public void onClick(View v) {
// Create a new HttpClient and Post Header
// Create a new HttpClient and Post Header
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://comparch2011.appspot.com/");
try {
// Add your data
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("name", "DEV"));
nameValuePairs.add(new BasicNameValuePair("message", "AndDev is Cool!"));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
// Execute HTTP Post Request
HttpResponse response = httpclient.execute(httppost);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
} catch (IOException e) {
// TODO Auto-generated catch block
}
}
-first thing first : you should use adb logcat. It will give you real time logs of your phone on your computers, it is incredibly useful to know what is going on.
-I suspect that you are making these calls in an Activity and in this case the app is simply crashing because of that : their is a safeguard to prevent you from doing that. It raises errors 'network on main thread' when necessary (like here).
The problem is that Activities are ran on the main thread, the one that is also used for the UI. so when you make such a network call, all the UI is blocked until the function has returned (and since it is waiting for the website to respond it can take a couple of seconds, which is very bad for the usability of your app).
The solution is to use an AsyncTask . It is an easy to use class that will allow you to make asynchronous calls (ie calls that don't block the UI).
As you can see in your LogCat, the error is a NetworkOnMainThreadException.
Which Android states here http://developer.android.com/reference/android/os/NetworkOnMainThreadException.html as:
NetworkOnMainThreadException:
The exception that is thrown when an application attempts to perform a
networking operation on its main thread.
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, but it's heavily
discouraged.
So take a look at http://developer.android.com/reference/android/os/AsyncTask.html instead, and be aware that the getResponse not should be called on the UI thread.
Alternatively you can probably just change the target or change the strictpolicy as follows, but I would no suggest doing so...
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
You shouldn't perform Network activities on the main thread. Because it doesn't allow the user to respond to the view when the network action is being performed.
Use an Asynctask, and it will work.
http://developer.android.com/reference/android/os/AsyncTask.html
Nithin
I have two Android mobile devices one v2.3 api 9 and one v3.1 honeycomb
I want to post an http api link for sms code. It turns that i got an error in honeycomb and the other mobile works fine this is the code
public void sendSMS(String phone_num, int password)
{
try
{
HttpClient hc = new DefaultHttpClient();
HttpPost post = new HttpPost("http://www.google.com/");
hc.execute(post); // I got an error here
}
catch(IOException e)
{
Log.e("error", "error");
}
}
StrictMode is enabled in HoneyComb, you must disable it to avoid NetworkOnMainThreadException
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
but that´s not recommended, use Asynctask, here you can find an example:
http://developer.android.com/reference/android/os/AsyncTask.html
You're experiencing this because of a new feature in Android Honeycomb. If you look through your logs you will see you are getting a NetworkOnMainThreadException Exception
In Android Honeycomb there is a new application policy that restricts the execution of time consuming calls on the main thread.
Please check your exception stack if you see the following: StrictMode$AndroidBlockGuardPolicy.onNetwork
What helped me was to read this and then fix my code to not use the main execution thread for the HTTP call.
100% working solution!
Place the following codes above your super.onCreate under protected void onCreate method:
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
Idea from Jorgesys! Thanks to him! Hope it solves your problem~
I had the same problem and cleared using Async Task.So dont call httppost request in main thread Instead use Async task to do http post.It also gives you more comfortable .link:http://www.vogella.com/articles/AndroidPerformance/article.html