Post Data to URL through Android App - android

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

Related

Http Request in AsyncTask Causes OutofMemory Error on Multiple Screen Rotations

I am a new Android programmer. My first major task was to create an Http Post request which runs in an AsyncTask in a fragment.
I have spent well over a hundred hours learning the ins and outs of AsyncTask and its many flaws and quirks. I have read hundreds of pages, performed hundreds of Google searches and read tens of thousands of words in an attempt to solve this issue. I have examined EVERY. SINGLE. TINY. ASPECT. of my code, removing and replacing it tiny piece by tiny piece, often line by line, and debugging, attempting to figure out what is going on here. All I have discovered is a burning dislike for Android and the methodologies behind it.
I create an activity. Lets call it "Login". I then create a fragment. Let's call it "LoginTaskFragment". When a user taps a button, the fragment runs the AsyncTask, which executes a request to a url. If the response takes a long while (I add a sleep into the script on the server side to simulate this), and the user rotates the screen over and over again, at some point, the app will crash, returning an Out of Memory error.
This happens if I run the task in a UI-less fragment or UI fragment. It happens even though I call setRetainInstance(true). I have checked and I am 100 percent positive that the AsyncTask is NOT being re-run on screen rotation. Now, if I remove the Http Post request entirely, I do not have the issue (or perhaps the memory leak is too small to have an effect, even after over a hundred rotations, which I've tried). The problem still occurs even if I call asyncTask.cancel(false) ... or true ... in onStop. Using the WeakReference trick mentioned often alongside AsyncTasks in many tutorials makes no difference whatsoever.
I am also using the savedInstanceState Bundle in the activity to save certain pertinent data in the activity itself, and I am not entirely clear if this affects the fragment's asynctask lifetime. But my understanding is not.
Honestly, I feel that this is ridiculous and should not be an issue. At all. Since Android happily destroys your objects on screen rotation, it should happily be responsible with GC as well, but of course, we all know, it's not. It seems to be a patchwork, bandaid-ed joke.
Here is some code where I initialize the fragment in the activity:
LoginTaskFragment loginFieldsTask = new LoginTaskFragment();
getSupportFragmentManager().beginTransaction().add(loginFieldsTask,"loginFieldsTask").commit();
Here is the relevant fragment code. If I strip out EVERYTHING, and just leave this, I have the problem, regardless of anything else in my code:
...
protected JsonObject doInBackground(Void... params) {
String postUrl="<some nice url here>";
ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("username", "un"));
nameValuePairs.add(new BasicNameValuePair("password", "pw"));
HttpParams httpParameters = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParameters, 10000);
HttpConnectionParams.setSoTimeout(httpParameters, 30000);
DefaultHttpClient httpClient = new DefaultHttpClient(httpParameters);
HttpPost httpPost = new HttpPost(postUrl);
try {
httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpClient.execute(httpPost);
httpClient.getConnectionManager().shutdown();
BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF-8"));
String json = reader.readLine();
JsonElement jElement = new JsonParser().parse(json);
JsonObject jObject = jElement.getAsJsonObject();
return jObject;
} catch (ClientProtocolException e) {
httpClient.getConnectionManager().shutdown();
} catch (IOException e) {
httpClient.getConnectionManager().shutdown();
} catch (Exception e) {
httpClient.getConnectionManager().shutdown();
}
return null;
}
I know that if I set the socket timeout to a low number, it DOES seem to kill the thread and I can rotate to my heart's content. But I would like to leave the timeout at 30 seconds as in the code above to allow for older phone network connectivity problems.
My understanding is that since the thread is in a fragment, it SHOULD NOT BE RECREATED when the screen rotates. And this seems to be true. onCreate is definitely not being called on rotation.
This is the line at which everything hinges on, of course:
HttpResponse response = httpClient.execute(httpPost);
I can't believe no one has had this exact problem, but after over a hundred hours searching and slamming my head against the wall, I've had enough. I need someone better than me at this to tell me what's going on.
Edit: Adding android:configChanges="orientation|keyboardHidden|screenSize" is not a good idea, and is heavily discouraged for this use as bad practice. See [Handling the Configuration Change Yourself here]. In fact, this is the whole point of using a UI-less fragment in the first place. The AsyncTask fragment is NEVER destroyed until the task within is complete. It is thus never recreated despite the fact that underlying activity IS being recreated over and over.
If you dont want to recreate your async task in each rotation ( config change ) then in your manifest file
android:configChanges="orientation|keyboardHidden|screenSize"
<activity
android:name="com.app.MainActivity"
android:configChanges="orientation|keyboardHidden|screenSize" >
OR
When you use dinamic fragments, you must use a frame layout, and put the fragment inside it.
<com.myproyect.TopMenu
android:id="#+id/menu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<!-- this was the problem
<fragment
android:id="#+id/fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.myproyect.HomeFragment"
android:layout_below="#id/menu"
/> -->
<FrameLayout android:id="#+id/fragment"
android:layout_width="match_parent" android:layout_height="match_parent"
android:layout_below="#id/menu"/>
<LinearLayout
...
>
</LinearLayout>
</RelativeLayout>
And instantiate the fragment inside the FrameLayout.
fragmentTransaction.replace(R.id.fragment, f);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
You can use
getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
in your fragment class to limit the rotation so that it will not re-execute the code when the rotation occurs.

android cancel previous http get request

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.

exception being thrown when performing http GET request from android [duplicate]

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.

Android HttpClient : NetworkOnMainThreadException

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.

Error on executing Http post in honeycomb

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

Categories

Resources