问题
I recently made a question based on doing a HTTP request with POST data (Found here: Android API 14 - POST Data to HTTP) and I was told I would need to try something like an AsyncTask because I cannot carry out Network Operations in the main thread.
In short form, I have no idea how to do this. Any help is appreciated! Here is my code:
package me.babblebox.application;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
public class BabbleBoxActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public void check_login() {
// Create a new HttpClient and Post Header
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://babblebox.me/android/test.php");
try {
// Add your data
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("id", "12345"));
nameValuePairs.add(new BasicNameValuePair("stringdata", "Hi"));
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
}
}
public void check_login_button(View v) {
check_login();
}
}
回答1:
Read about Processes and threads also AsyncTask.
The following is far from perfect but you could try something like this to get started...
public class BabbleBoxActivity extends Activity {
// Leave onCreate() as it is
public void check_login_button(View v) {
PostTask postTask = new PostTask();
postTask.execute();
}
// EDITED THE LINE BELOW TO INCLUDE 'class'
private class PostTask extends AsyncTask<Void, Void, Void> {
// Move the code that was in check_login to the
// doInBackground method below
protected Void doInBackground(Void... params) {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://babblebox.me/android/test.php");
try {
// Add your data
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("id", "12345"));
nameValuePairs.add(new BasicNameValuePair("stringdata", "Hi"));
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
}
return null;
}
}
}
In reality you'll need to learn how to pass paramaters into the AsyncTask
and get it to return valid results.
EDIT:
Just out of interest, I put together your original code (without AsyncTask but on Android v2.2 which allows network operations on main thread). I added some logging code just to check the connection worked...
HttpResponse response = httpclient.execute(httppost);
Header[] headers = response.getAllHeaders();
Log.d("BabbleBox", "Header count: " + headers.length);
for (int c = 0; c < headers.length; c++)
Log.d("Babblebox", "Header: name=" + headers[c].getName() + " value=" + headers[c].getValue());
...and I got the following response headers.
Header count: 6
Header: name=Date value=Sun, 11 Dec 2011 16:38:19 GMT
Header: name=Server value=LiteSpeed
Header: name=Connection value=close
Header: name=X-Powered-By value=PHP/5.3.8
Header: name=Content-Type value=text/html
Header: name=Content-Length value=4
The response from any web 'request' (GET, POST, PUT) will vary depending on the remote service you are talking to. You'll need to work out what your server is going to return and then process the response accordingly.
回答2:
If you do not want AsyncTask
(for whatever reasons) you, probably, can do something like
public void checkLoginAsync() {
Executors.newSingleThreadExecutor(new Runnable(){
@Override
public void run() {
checkLogin();
});
}
You would probably make checkLogin()
to accept some knd of a listener then so it reports something like onLoginError
and onLoginSucess
to, say, your activity implementing that listener. Or maybe to your application so you can, say, terminate the program regardless of what activity is currently showing.
来源:https://stackoverflow.com/questions/8464744/android-api-14-network-operations-asynctask