I want to make a simple HTTP Head Request to URL which is fetched from a text box. Everytime I enter the URL and Click to get the HTTP response, the App Become Irrespnosive. Here is the code :
public void MakeRequest(View v)
{
EditText mEdit;
TextView txtresponse;
txtresponse = (TextView)findViewById(R.id.textView1);
mEdit = (EditText)findViewById(R.id.editText1);
HttpClient httpClient = new DefaultHttpClient();
HttpHead httphead = new HttpHead(mEdit.getText().toString());
try {
HttpResponse response = httpClient.execute(httphead);
txtresponse.setText(response.toString());
} catch (ClientProtocolException e) {
// writing exception to log
e.printStackTrace();
} catch (IOException e) {
// writing exception to log
e.printStackTrace();
}
}
Never perform long running tasks on the UI Thread (and HTTP Request / Response can take very long due to server latency).
Run the HTTP handling in a background thread.
There are several examples on Stackoverflow - like Make an HTTP request with android and of course read up on Android site - http://developer.android.com/training/articles/perf-anr.html
You are probably doing the request in the UI thread. This is bad practice, as it is in charge of all work done for the UI. You can read more about this here.
A better way would be to do this in another thread. This can be done with e.g.
a custom worker thread or
an AsyncTask.
Example with an AsyncTask (this goes inside your class):
public void MakeRequest(View v)
{
EditText mEdit;
mEdit = (EditText)findViewById(R.id.editText1);
new RequestTask().execute(mEdit.getText().toString());
}
private class RequestTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
HttpClient httpClient = new DefaultHttpClient();
HttpHead httphead = new HttpHead(params[0]);
try {
HttpResponse response = httpClient.execute(httphead);
return response.toString();
} catch (ClientProtocolException e) {
// writing exception to log
e.printStackTrace();
} catch (IOException e) {
// writing exception to log
e.printStackTrace();
}
return "";
}
#Override
protected void onPostExecute(String result) {
TextView txtresponse;
txtresponse = (TextView)findViewById(R.id.textView1);
txtresponse.setText(result);
}
#Override
protected void onPreExecute() {}
#Override
protected void onProgressUpdate(Void... values) {}
}
Related
Friends ,i need help to android httppost data to server using Asynctask or Threads
I need to send data to my server when i click post button.But when i click it app need to go to next page and data need to send through as background process.I'm new to Android.I don't know what is exactly use for this kind of task (Threads or Asyanctask).
I tried this code but it will give me exception error
public void startProgress(final String name) {
// Do something long
Runnable runnable = new Runnable() {
#Override
public void run() {
try {
Thread.sleep(500);
send(name);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
new Thread(runnable).start();
}
public void send(String name)
{
// get the message from the message text box
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://10.0.2.2:8080/Test");
try {
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
String co2 =input_field.getText().toString();
nameValuePairs.add(new BasicNameValuePair("Name", name));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
Toast toast = Toast.makeText(getApplicationContext(), "Got it ", Toast.LENGTH_SHORT);
toast.show();
httpclient.execute(httppost);
input_field.setText("");
} catch(Exception e){
Toast toast2 = Toast.makeText(getApplicationContext(), "error", Toast.LENGTH_SHORT);
toast2.show();
}
}
but if i use it this way it works.(text is TextView item in that page)
public void startProgress(final String name) {
// Do something long
Runnable runnable = new Runnable() {
#Override
public void run() {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
text.post(new Runnable() {
#Override
public void run() {
send(name);
}
});
}
};
new Thread(runnable).start();
}
What happen in bellow piece of code can you please explain about this also
text.post(new Runnable() {
#Override
public void run() {
send(name);
}
});
please help me to solve this problem.If there is better way to do my need please mentioned it .Because it have very less experience about Android development
You can do this by using AsyncTask like this:
public class HttpPostExanple extends AsyncTask<String, Void, String>
{
#Override
protected String doInBackground(String... params)
{
BufferedReader inBuffer = null;
String url = "http://10.0.2.2:8080/Test";
String result = "fail";
try {
HttpClient httpClient = new DefaultHttpClient();
HttpPost request = new HttpPost(url);
List<NameValuePair> postParameters = new ArrayList<NameValuePair>();
postParameters.add(new BasicNameValuePair("name", params[0]));
UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(
postParameters);
request.setEntity(formEntity);
httpClient.execute(request);
result="got it";
} catch(Exception e) {
// Do something about exceptions
result = e.getMessage();
} finally {
if (inBuffer != null) {
try {
inBuffer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return result;
}
protected void onPostExecute(String page)
{
//textView.setText(page);
Toast toast = Toast.makeText(getApplicationContext(), page, Toast.LENGTH_SHORT);
toast.show();
}
}
And you need to have this in your main method
new HttpPostExample().execute(new String[] {name});
Check this out.
Hope this will help you.
You should implement something like this:
new Thread(new Runnable() {
public void run() {
send(name); // if this method need to access the UI interface you have to use .post method
}
}).start();
About your question: the .post method causes the Runnable to be added to the message queue. The runnable will be run on the user interface thread. [reference]
And this is required because without this method you violate the single thread model: the Android UI toolkit is not thread-safe and must always be manipulated on the UI thread. In your piece of code, the TextView is manipulated on a worker thread, which can cause really weird problems.
As you can see, If the method inside your thread need to access the UI you should use .post method, and this make more laborious the code. So the right solution may be use the AsyncTask that will manage for you the complexity of the threads. You have to put the piace of code that need to access on the UI, in the onPostExecute() method
I suggest you to use robospice or other frameworks as alternative:
Volley
DataDroid
REST Provider
REST Droid
PostMan (rings twice) Lib
Ion
droidQuery
Android Job Queue
Goro
because activity can be recreated before onPostExecute reached. AsyncTask is not good example for networking in Activity.
I know Java but unfortunately chosen Basic4Android for Android Development. After working over an year I realized I should move in native solution. So my question might be silly but I need your advice to solve it.
My goal is to retrieve data from a GET request. I've tried tons of android http client tutorials over internet but failed with each tutorial. I'm just going to share one here so that you can help me to fix. When I'm clicking on the button, nothing is happening without tons of error message in logcat window.
Main Class is here for a quick review:
public class MainActivity extends Activity implements OnClickListener {
private Button Test;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Test = (Button) findViewById(R.id.Test);
Test.setOnClickListener(this);
}
#Override
public void onClick(View v) {
if (v.getId() == R.id.Test){
try {
HttpClient client = new DefaultHttpClient();
String getURL = "http://www.google.com";
HttpGet get = new HttpGet(getURL);
HttpResponse responseGet = client.execute(get);
HttpEntity resEntityGet = responseGet.getEntity();
if (resEntityGet != null) {
// do something with the response
String response = EntityUtils.toString(resEntityGet);
Log.i("GET RESPONSE", response);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
And the whole project is here: https://dl.dropboxusercontent.com/u/15625012/TestHttp.zip
I'll really appreciate any sort of help/advice.
you are currently doing a network access in your main UI thread (Button click function). Android does not allow long operations such as network access in the main thread UI thread of the app. You need to do this asynchronously in a separate thread. You can use built in Async Class for this purpose.
Here is a sample code i wrote
public class Sample extends Activity
{
private ProgressDialog progress_dialog;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sample);
progress_dialog = new ProgressDialog(this);
}
public void MyButtonClick(View view)
{
EditText usernameEditText = (EditText)findViewById(R.id.sample_username);
String username = usernameEditText.getText();
String URL = "http://SOME_WEBSITE?Username=" + username;
progress_dialog.setMessage("Loading. Please wait...");
progress_dialog.setCancelable(false);
progress_dialog.show();
new SampleAsynThread().execute(URL);
}
private class SampleAsynThreadextends AsyncTask <String, Void, String>
{
protected String doInBackground(String... urls)
{
// make your request here
return "Response";
}
protected void onPostExecute(String result)
{
// show response on ui
progress_dialog.dismiss();
}
}
protected void onDestroy()
{
progress_dialog.dismiss();
super.onDestroy();
}
#Override
protected void onPause()
{
progress_dialog.dismiss();
super.onPause();
}
}
First- always post the errors in logcat here, we almost always need them to fix the problem.
But here it's easy- you can't do network IO on the main thread. You need to run it on an AsyncTask or a Thread instead.
try {
URL url = new URL(urlstr);
HttpsURLConnection connection =
(HttpsURLConnection)url.openConnection();
connection.setReadTimeout(6000);
connection.setRequestMethod("GET");
connection.setRequestProperty("User_agent", "android");
OutputStream os = connection.getOutputStream();
//os.write(buffer);
InputStream is = connection.getInputStream();
} catch (MalformedURLException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}catch (Exception e) {
// TODO: handle exception
}
I'm developing an Android app. I want to post to a server using asynctask. However, I still have an error which indicates that the UI thread is blocked.
I want to parse the XML response and display it in a list view, but I cannot proceed because the UI thread is still blocked.
public class AsynchronousPost extends ListActivity implements OnClickListener {
EditText SearchValue;
Button SearchBtn;
String URL = "";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.search_interface);
SearchBtn = (Button) findViewById(R.id.searchbtn);
SearchBtn.setOnClickListener(this);
}
public void onClick(View views) {
new MyAsyncTask().execute();
}
private class MyAsyncTask extends AsyncTask<String, Integer, Document> {
private final String URL = "url";
private final String username = "username";
private final String password = "password";
private EditText SearchValue;
#Override
protected Document doInBackground(String... arg0) {
// TODO Auto-generated method stub
getXmlFromUrl(URL); // getting XML
return null;
}
#Override
protected void onPostExecute() {
//want to parse xml response
//display on listview
}
public String getXmlFromUrl(String url) {
String xml = null;
try {
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
SearchValue = (EditText) findViewById(R.id.search_item);
String Schvalue = SearchValue.getText().toString();
// Add your data
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(
5);
nameValuePairs
.add(new BasicNameValuePair("username", username));
nameValuePairs
.add(new BasicNameValuePair("password", password));
nameValuePairs.add(new BasicNameValuePair("searchItem",
Schvalue));
// response stored in response var
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
xml = EntityUtils.toString(httpEntity);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return null;
} catch (ClientProtocolException e) {
e.printStackTrace();
return null;
} catch (IOException e) {
e.printStackTrace();
return null;
}
// return XML
return xml;
}
}
}
There are a couple problems that I see. First, you aren't passing anything in execute() but in your class declaration you are telling doInBackground() to expect a String. Secondly, you are telling onPostExecute() to expect a Document but you are returning null from doInBackground() and not taking any parameters in onPostExecute(). Unless I missed something, I don't see how this even compiles
protected Object doInBackground(String... params) {
//this method of AsyncTask is not running on the UI Thread -- here do just non UI taks
return result;
}
#Override
protected void onPostExecute(Object result) {
//I'm not sure but I think this method is running on the UI Thread
//If you have long operations here to do you will block UI Thread
//put the tasks in the doInBackground...
//to fill the elements in the UI elements use
//
runOnUiThread (new Runnable() {
#Override
public void run() {
//here fill your UI elements
}});
}
I am getting the exception android.os.NetworkOnMainThreadException when I tried to use the following codes:
public class CheckServer extends Activity{
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
Runnable runn = null;
HttpTask.execute(runn);
}
private class HttpTask extends AsyncTask<String, String, String>
{
#Override
protected String doInBackground(String... params) {
// TODO Auto-generated method stub
HttpURLConnection urlConnection = null;
URL theURL = null;
try {
theURL = new URL("http://192.168.2.8/parkme/Client/clientquery.php?ticket=66t");
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
urlConnection = (HttpURLConnection) theURL.openConnection();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String response = null;
try {
response = readInputStream(urlConnection.getInputStream());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return response;
}
private String readInputStream(InputStream is) {
// TODO Auto-generated method stub
String line = "";
StringBuilder total = new StringBuilder();
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
try {
while ((line = rd.readLine()) != null) {
total.append(line);
}
} catch (Exception e) {
e.printStackTrace();
}
return total.toString();
}
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
Toast.makeText(getApplicationContext(), result, Toast.LENGTH_LONG).show();
}
}}
If possible can someone tell me how to use it inside an Async Task and get the output? I tried but can't seem to get anywhere.
NetworkOnMainThread Exception occurs because you are running a network related operation on the main UI Thread.This is only thrown for applications targeting the Honeycomb SDK or higher
You should be using asynctask.
http://developer.android.com/reference/android/os/AsyncTask.html
In onCreate()
new TheTask().execute();
You can also pass parameters like url to the constructor of AsyncTask and use the same in doInBackground()
class TheTask extends AsyncTask<Void,Void,Void>
{
protected void onPreExecute()
{ super.onPreExecute();
//display progressdialog.
}
protected void doInBackground(Void ...params)//return result here
{
//http request. do not update ui here
return null;
}
protected void onPostExecute(Void result)//result of doInBackground is passed a parameter
{
super.onPostExecute(result);
//dismiss progressdialog.
//update ui using the result returned form doInbackground()
}
}
When an asynchronous task is executed, the task goes through 4 steps:
onPreExecute(), invoked on the UI thread before the task is executed. This step is normally used to setup the task, for instance by showing a progress bar in the user interface.
doInBackground(Params...), invoked on the background thread immediately after onPreExecute() finishes executing. This step is used to perform background computation that can take a long time. The parameters of the asynchronous task are passed to this step. The result of the computation must be returned by this step and will be passed back to the last step. This step can also use publishProgress(Progress...) to publish one or more units of progress. These values are published on the UI thread, in the onProgressUpdate(Progress...) step.
onProgressUpdate(Progress...), invoked on the UI thread after a call to publishProgress(Progress...). The timing of the execution is undefined. This method is used to display any form of progress in the user interface while the background computation is still executing. For instance, it can be used to animate a progress bar or show logs in a text field.
onPostExecute(Result), invoked on the UI thread after the background computation finishes. The result of the background computation is passed to this step as a parameter.
Ok, lets do it step by step ...
1) create private class extending AsyncTask
private class HttpUrlConnectionTask extends AsyncTask {
2) Override the doInBackground() method, this will do the heavy load
#Override
protected Object doInBackground(Object... params) {
// your HttpUrlConnection code goes here
return response;
3) Once the job is done and returns, the onPostExecute() method will be called. The result parameter contains the return value of doInBackground() - so response.
#Override
protected void onPostExecute(Object result) {
Within this method you can update your UI.
4) Finally lets have a look onto the HttpUrlConnection code
HttpURLConnection urlConnection = null;
URL theURL = new URL(url);
urlConnection = (HttpURLConnection) theURL.openConnection();
String response = readInputStream(urlConnection.getInputStream());
return response;
Hope this helps. Happy coding!
#Raghunandan comes with a really good explanation of how AsyncTask works
Here you go:
public static class InitializeTask extends MyAsyncTask<String, String, String> {
private Activity activity;
private ProgressDialog dialog;
public InitializeTask(Activity activity) {
this.activity = activity;
}
#Override
protected void onPostExecute(String result) {
Toast.makeText(activity, result, Toast.LENGTH_SHORT).show();
}
#Override
protected String doInBackground(String... params) {
HttpClient httpclient = new DefaultHttpClient();
HttpGet httpget = new HttpGet("http://192.168.2.8/localhost/parkme/Client/clientquery.php?ticket=");
try {
HttpResponse response = httpclient.execute(httpget);
if(response != null) {
String line = "";
InputStream inputstream = response.getEntity().getContent();
return convertStreamToString(inputstream);
} else {
return "Unable to complete your request";
}
} catch (ClientProtocolException e) {
return "Caught ClientProtocolException";
} catch (IOException e) {
return "Caught IOException";
}
}
private String convertStreamToString(InputStream is) {
String line = "";
StringBuilder total = new StringBuilder();
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
try {
while ((line = rd.readLine()) != null) {
total.append(line);
}
} catch (Exception e) {
return "Stream Exception";
}
return total.toString();
}
}
A little side note, it is generally considered bad code to catch just Exception, since this will catch anything, and you are not accounting for what it is.
To use the AsyncTask in the Activity do this:
InitializeTask task = new InitializeTask(this)
task.execute()
Exactly as it says, network activity isn't allowed on the thread the activity ran in. Moving your code to an Asynctask is the way to do it properly. Though if you're just trying to get your concept working still you can do this...
//lazy workaround with newer than gingerbread
//normally UI thread can't get Internet.
if(Build.VERSION.SDK_INT >= 9){
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
And then the UI thread actually can. I wouldn't release anything like this however, I haven't even tried infact. It's just my lazy debugging move I use a lot.
I'm very new to android programming and I tried to call a php web service from android using HttpClient. But while app is running it's stopped saying "Unfortunately ServiceTest is stopped" and terminated.
Following is my code.
public class ServiceTestActivity extends Activity {
private Button btn;
private TextView txt;
String result = "";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btn = (Button) findViewById(R.id.button1);
txt = (TextView) findViewById(R.id.txt_name);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
callWebErvice("http://localhost/mvc/login/test");
}
});
}
public void callWebErvice(String serviceURL) {
HttpClient httpclient = new DefaultHttpClient();
HttpGet request = new HttpGet(serviceURL);
ResponseHandler<String> handler = new BasicResponseHandler();
try {
result = httpclient.execute(request, handler);
txt.setText(result);
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
httpclient.getConnectionManager().shutdown();
Log.i("my result", result);
} // end callWebServe
}
Can anybody find out the reason for this?
There are three types of operations which we should never perform on UI thread.
Network operations.
DB operations
File operations.
From your code I can see that you are performing network operation on UI thread and it will definitely lead you into ANR (Application Not Responding).
Whenever ANR happens of application, android just kills the application.
You will have to use worker thread to perform Network Operation.