Threads and Asynctask task use for httppost - android

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.

Related

Toast does not appears when thread completes its execution

I have a AsyncTask<Task, Void, Boolean> thread in my Android application. And I want to show message through Toast.makeText() when this thread completes its execution. For this I have added Toask.makeText() inside if as well as inside else of doInBackground method. The thread is completing its execution succesfully but the toast's message does not appears. So what can be the problem?
Code:
#Override
protected Boolean doInBackground(Task... arg0) {
try {
Task task = arg0[0];
QueryBuilder qb = new QueryBuilder();
HttpClient httpClient = new DefaultHttpClient();
HttpPost request = new HttpPost(qb.buildContactsSaveURL());
StringEntity params =new StringEntity(qb.createTask(task));
request.addHeader("content-type", "application/json");
request.setEntity(params);
HttpResponse response = httpClient.execute(request);
if(response.getStatusLine().getStatusCode()<205)
{
/*this is the message inside if*/
Toast.makeText(context, "inside -IF", Toast.LENGTH_SHORT).show();
return true;
}
else
{
/*this is the message inside else*/
Toast.makeText(context, "inside -ELSE", Toast.LENGTH_SHORT).show();
return false;
}
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
Toast work in Main thread you are trying to show Toast in Background Thread (doInBackground). Move your toast code to onPostExecution callaback and you will be able to see Toasts.
The Task it is doing is in background, it won't show toast as it is in background.
Background tasks don't affect your UI or main thread.
The thread is completing its execution succesfully but the toast's
message does not appears
Because doInBackground method run on non-ui-Thread. and application only show Alert,Toast and update UI elements from UI-Thread only.
To show Toast from doInBackground wrap Toast related code inside runOnUiThread method
OR
return response from doInBackground method and use onPostExecute method to show Toast.
As mentioned by other people, you shouldn't have any UI related changes/activities on the background thread. Do it on the main thread which onPostExecute method does. Here's an example
private class DoSomethingTask extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
//Do background process here. Make sure there are no UI related changes here
return null;
}
protected void onPostExecute(Void x)
{
//Do UI related changes here
}
}
Using your code:
private class DoSomethingTask extends AsyncTask<Void, Void, Void> {
int statusCode;
#Override
protected Void doInBackground(Task... arg0) {
try {
Task task = arg0[0];
QueryBuilder qb = new QueryBuilder();
HttpClient httpClient = new DefaultHttpClient();
HttpPost request = new HttpPost(qb.buildContactsSaveURL());
StringEntity params =new StringEntity(qb.createTask(task));
request.addHeader("content-type", "application/json");
request.setEntity(params);
HttpResponse response = httpClient.execute(request);
statusCode = response.getStatusLine().getStatusCode();
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
protected void onPostExecute(Void x)
{
//Do UI related changes here
if(statusCode < 205)
{
/*this is the message inside if*/
Toast.makeText(context, "inside -IF", Toast.LENGTH_SHORT).show();
return true;
}
else
{
/*this is the message inside else*/
Toast.makeText(context, "inside -ELSE", Toast.LENGTH_SHORT).show();
return false;
}
}
}
Hope this helps!

Android thread finished callback

I want execute http post after getting response from server.
If server response is false the http post will execute else not execute.
How can i do for this.
My android main activity code:
if (Utility.isValidMobile(mobileNumber)) {
String isAvailable = userDelegate.checkUser(mobileNumber, context);
if (isAvailable.equals("false")) {
userDelegate.addUser(userMO, context);
Toast.makeText(getApplicationContext(), "Your mobile number is" + mobileNumber + "name is" + userName, Toast.LENGTH_LONG).show();
} else if (isAvailable.equals("true")) {
Toast.makeText(getApplicationContext(), "Your mobile number is already registerd", Toast.LENGTH_LONG).show();
}
}
when i click signup button this above code will executed
My Userdelegate class code :
public void addUser(final UserMO userMo, final Context context) {
final String jsonStringObject = gson.toJson(userMo);
Thread t = new Thread() {
public void run() {
Looper.prepare(); // for the child Thread
HttpClient client = new DefaultHttpClient();
HttpConnectionParams.setConnectionTimeout(client.getParams(), 10000); // Timeout
// Limit
try {
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("userBO", jsonStringObject));
HttpPost post = new HttpPost("http://192.168.1.101:8080/warname/user/addUser");
post.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = client.execute(post);
BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
Toast.makeText(context, "Your user id " + rd.readLine(), Toast.LENGTH_LONG).show();
} catch (Exception e) {
e.printStackTrace();
}
Looper.loop(); // Loop in the message queue
}
};
t.start();
}
public void getMatchingExistingUserList(final String mobile_number, final Context context) {
final String jsonStringObject = gson.toJson(mobile_number);
Thread t = new Thread() {
public void run() {
Looper.prepare(); // for the child Thread
HttpClient client = new DefaultHttpClient();
HttpConnectionParams.setConnectionTimeout(client.getParams(), 10000); // Timeout
// Limit
try {
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("userBO", jsonStringObject));
HttpPost post = new HttpPost("http://192.168.1.101:8080/warname/user/addUser");
post.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = client.execute(post);
BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
final String responseString = rd.readLine();
} catch (Exception e) {
e.printStackTrace();
}
Looper.loop(); // Loop in the message queue
}
};
t.start();
}
public String checkUser(final String mobile_number, final Context context) {
final StringBuilder isAvailable = new StringBuilder();
Thread t = new Thread() {
#Override
public void run() {
Looper.prepare(); // for the child Thread
try {
HttpClient client = new DefaultHttpClient();
HttpConnectionParams.setConnectionTimeout(client.getParams(), 10000); // Timeout
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("MobileNumber", gson.toJson(mobile_number)));
HttpPost post = new HttpPost("http://192.168.1.101:8080/warname/user/checkUserMobileNumber");
post.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = client.execute(post);
BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
isAvailable.append(rd.readLine());
} catch (Exception e) {
e.printStackTrace();
}
Looper.loop(); // Loop in the message queue
}
};
t.start();
return isAvailable.toString();
}
Problem is i got response false but the if condition not working.
how to solve this problem.
After changing:
if (Utility.isValidMobile(mobileNumber)) {
new AsyncTask<Void, Void, String>() {
#Override
protected String doInBackground(Void... arg0) {
return userDelegate.checkUser(mobileNumber, context);
}
#Override
protected void onPostExecute(String isAvailable) {
Toast.makeText(getApplicationContext(), isAvailable, Toast.LENGTH_LONG).show();
if (isAvailable.equals("false")) {
Toast.makeText(getApplicationContext(), "Your mobile number is" + mobileNumber + "name is" + userName, Toast.LENGTH_LONG).show();
userDelegate.addUser(userMO, context);
} else if (isAvailable.equals("true")) {
Toast.makeText(getApplicationContext(), "Your mobile number is already registerd", Toast.LENGTH_LONG).show();
}
}
}.execute(null, null, null);
}
The if condition is not working ?
If server response is false the http post will execute else not
execute. How can i do for this
Issue occurring because you are using Threads in checkUser and addUser. Thread's execute with-out stopping execution of current Thread.
For example, when checkUser method is called from main thread then final StringBuilder isAvailable = new StringBuilder(); executing on main thread and Thread t is executing in separately. so system return control to next line which is return isAvailable.toString(); without waiting Thread execution complete means checkUser method always return null or empty string.
Same is for addUser method.
To do task accoding to result of checkUser method response use AsyncTask class.
You are using new threads to do http request here. Therefore your delegate methods are not synchronized. addUser and checkUser will return before your http requests finish.
To write multi thread codes like yours, you may want to use a some kind of a listener to do the threads communication work.
For example, you can pass a listener to your delegate which looks like this
class Listener{
private Handler handler = new Handler();
public void onUserAdded(){
handler.post(new Runnable(){
public void run(){
// Toast your thing
}
});
}
public void onUserChecked(final boolean available){
handler.post(new Runnable(){
public void run(){
if(available){
// Toast your thing
}else{
userDelegate.addUser(userMO, context);
}
}
});
}
}
And all your new Thread(){ run(){ codes should end with all call to the listener.
As you can see I use a Handler to post works back to the UI thread. This is very important for you to notify your UI elements of what is going on in your none-UI threads.
Also, I can't see what you are doing with your Looper.prepare() and Looper.loop(). No child thread is there.

Can't create handler inside thread that has not called Looper.prepare() in android

I am getting can't create handler inside thread in asynchronous background task. Below is my code. I made the necessary modifications to progress bar after searching in google but still the error is rising. Please help me with this. Will be thankful.
My code:
private class LongOperation1 extends AsyncTask<String, Void, String> {
private final WeakReference<MainActivity> mainActivityWeakRef;
ProgressDialog dialog;
public LongOperation1(MainActivity mainActivity) {
super();
this.mainActivityWeakRef = new WeakReference<MainActivity>(
mainActivity);
// this.activity = mainActivity;
}
#Override
protected String doInBackground(String... params) {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(
"http://.............php");
// This is the data to send
// String MyName = 'adil'; //any data to send
// publishProgress(5);
try {
// Add your data
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(
1);
nameValuePairs.add(new BasicNameValuePair("param1", "1"));
nameValuePairs.add(new BasicNameValuePair("param2",
"Cities"));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
// Execute HTTP Post Request
ResponseHandler<String> responseHandler = new BasicResponseHandler();
String response = httpclient.execute(httppost, responseHandler);
// This is the response from a php application
String reverseString = response;
Toast.makeText(MainActivity.this, "response" + reverseString,
Toast.LENGTH_LONG).show();
} catch (ClientProtocolException e) {
Toast.makeText(MainActivity.this,
"CPE response " + e.toString(), Toast.LENGTH_LONG)
.show();
// TODO Auto-generated catch block
} catch (IOException e) {
Toast.makeText(MainActivity.this,
"IOE response " + e.toString(), Toast.LENGTH_LONG)
.show();
// TODO Auto-generated catch block
}
return "All Done!";
}
#Override
protected void onPostExecute(String result) {
Log.d("onpostexecute", (mainActivityWeakRef.get() != null) + "");
if (mainActivityWeakRef.get() != null
&& !mainActivityWeakRef.get().isFinishing()) {
AlertDialog alertDialog = new AlertDialog.Builder(
mainActivityWeakRef.get()).create();
alertDialog.setTitle(result);
alertDialog.setMessage("On post execute");
alertDialog.setCancelable(false);
alertDialog.setButton(AlertDialog.BUTTON_POSITIVE, "OK",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int which) {
dialog.dismiss();
}
});
alertDialog.show();
}
}
#Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
dialog.incrementProgressBy(5);
}
}
You can not update the UI thread(Main Thread) from another thread.. If you want to do it
1) Return your response String from doInbackground, and update the UI in PostExecute()
2)Otherwise you can wrap the Toast Message in runonUiThread(){}
3) Use Handler to update the UI from another thread.
You cannot use Toast in the do in background operation because you need the UIThread to show them. Instean of doing that as you did. Use a variable an save it for different states.
In onPostExecute check the variable and show the corresponding Toast.
Hope it helps.

Android HTTP Request Making App Irresponsive

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) {}
}

How to make Toast to display LogCat text?

I have an HttpPost which sends data to a server to be stored on a database. When that data is successfully stored I get a response in my LogCat that says "message has been saved successfully" (this response was defined in my PHP code). I am happy with that, but I am trying to get that same response to be displayed in a Toast. Here is my code:
String myBreadfromr, myBreadtor;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
Bundle myBasket = getIntent().getExtras();
myBreadfromr = myBasket.getString("keyfromcellr");
myBreadtor = myBasket.getString("keytocellr");
new SendData().execute("");
}
public class SendData extends AsyncTask<String, Integer, Void> {
protected void onPreExecute(String f) {
// called before doInBackground has started
f = "f";
}
protected Void doInBackground(String... params) {
// TODO Auto-generated method stub
// Create a new HTTP client
HttpClient client = new DefaultHttpClient();
// Create a new HTTP Post
HttpPost post = new HttpPost("http://192.xxx.xxx.xxx/androidp2p/process.php");
try {
// Add the data
List<NameValuePair> pairs = new ArrayList<NameValuePair>(3);
pairs.add(new BasicNameValuePair("from", myBreadfromr));
pairs.add(new BasicNameValuePair("to", myBreadtor));
pairs.add(new BasicNameValuePair("message", "What is your location?"));
// Encode Post data into valid URL format
post.setEntity(new UrlEncodedFormEntity(pairs));
// Go back to the first page
Intent back2start = new Intent(RequestLocation.this, StartApp.class);
startActivity(back2start);
// Make the HTTP Post Request
HttpResponse response = client.execute(post);
// Convert the response into a String
final HttpEntity resEntity = response.getEntity();
// Write the response to a log file
if (resEntity != null) {
Log.i("RESPONSE", EntityUtils.toString(resEntity));
}
runOnUiThread(new Runnable(){
public void run() {
Toast.makeText(RequestLocation.this, resEntity.toString(), Toast.LENGTH_LONG).show();
}
});
} catch (UnsupportedEncodingException uee) {
uee.printStackTrace();
} catch (ClientProtocolException cpe) {
cpe.printStackTrace();
} catch (IOException ioe) {
ioe.printStackTrace();
}
return null;
}
protected void onProgressUpdate(Integer... progress) {
// called when the background task has made any progress
}
protected void onPostExecute() {
// called after doInBackground has finished
}
}
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
}
What I see in the Toast instead is: "org.apache.http.conn.BasicManagedEntity#41284b48".
Thanking you in advance for any help in resolving this matter.
Use EntityUtils.toString(resEntity) in the Toast to get the same text.
Also no need to call runOnUiThread, doInBackground must return something, not null, and that something will be available onPostExecute which already is made to run on the UI thread.
AsyncTask

Categories

Resources