首先,http协议是无状态的连接,之前的两种方式get,与post连接方式,每点击一次就启动了一个线程,而在启动线程时
很自然的就重新的new出了一个新的HttpClient,相当于两个客户端向服务器发送了请求,这在实际应用中显然是不合理的,由
于Android中没有浏览器类似的Cookie管理机制,所以我们必须保证在Android客户端启动之后,我们对服务器访问的是同一个
Client。这里用到的思想主要是单例,加上同步机制,以下是一个简单的实现案例:
MainActivity.java:
package com.example.test003; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import org.apache.http.NameValuePair; import org.apache.http.message.BasicNameValuePair; import org.json.JSONException; import org.json.JSONObject; import com.example.test003.MainActivity; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.app.Activity; import android.view.Menu; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import android.widget.Toast; public class MainActivity extends Activity { private EditText et1; private EditText et2; private Button btn1; private Button btn2; private TextView tv3; private Handler handler; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); et1 = (EditText) super.findViewById(R.id.editText1); et2 = (EditText) super.findViewById(R.id.editText2); tv3 = (TextView)super.findViewById(R.id.textView3); btn1 = (Button)super.findViewById(R.id.button1); btn2 = (Button)super.findViewById(R.id.button2); handler = new Handler(){ @Override public void handleMessage(Message msg) { switch (msg.what) { case 1: try { JSONObject obj = (JSONObject) msg.obj; String result = obj.getString("result"); if(result.equals("1")){ Toast.makeText(MainActivity.this, "欢迎您"+obj.getString("cname"),3000).show(); }else{ Toast.makeText(MainActivity.this, "登陆失败",3000).show(); } } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } break; case 2: String info = (String) msg.obj; Toast.makeText(MainActivity.this, info,3000).show(); break; } } }; btn2.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View arg0) { new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub InputStream iis = YcHttpClient.post("http://192.168.14.194:8080/HttpClient_Server/back/index.jsp", null); byte[] bs = IOUtil.read(iis); String s = new String(bs); Message m = new Message(); m.what = 2; m.obj = s; handler.sendMessage(m); } }).start(); } }); btn1.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View arg0) { // TODO Auto-generated method stub new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub String cname = et1.getText().toString().trim(); String password = et2.getText().toString().trim(); String op = "login"; List<NameValuePair> params = new ArrayList<NameValuePair>(); params.add(new BasicNameValuePair("cname", cname)); params.add(new BasicNameValuePair("password", password)); params.add(new BasicNameValuePair("op",op)); InputStream iis = YcHttpClient.post(Constants.ADDRESS, params); try { byte[] bs = IOUtil.read(iis); String s = new String(bs); JSONObject obj = new JSONObject(s); Message m = new Message(); m.what = 1; m.obj = obj; handler.sendMessage(m); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }).start(); } }); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main, menu); return true; } }
UserHttpClient.java:
package com.example.test003; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.List; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.HttpVersion; 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.conn.ClientConnectionManager; import org.apache.http.conn.params.ConnManagerParams; import org.apache.http.conn.scheme.PlainSocketFactory; import org.apache.http.conn.scheme.Scheme; import org.apache.http.conn.scheme.SchemeRegistry; import org.apache.http.conn.ssl.SSLSocketFactory; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager; import org.apache.http.params.BasicHttpParams; import org.apache.http.params.HttpConnectionParams; import org.apache.http.params.HttpParams; import org.apache.http.params.HttpProtocolParams; import org.apache.http.protocol.HTTP; import android.util.Log; /** * 单例模式,为解决Http协议无状态,模拟一次持久的链接状态 * 构造方法私有化 对外提供一个getHttpClient方法, * 并且让这个方法同步,来解决多线程访问的问题 * @author dell * */ public class UserHttpClient { private static final String CHARSET = HTTP.UTF_8; private static HttpClient userHttpClient; private static final String TAG = "userHttpClient"; //构造方法私有化 private UserHttpClient() { } //对外提供getHttpClient方法 public static synchronized HttpClient getHttpClient() { //如果userHttpClient == null 即原来没有 userHttpClient 第一次链接 if (null == userHttpClient) { // This interface represents a collection of HTTP protocol parameters //这是一个Http协议的集合,里面存放了Http协议的相应参数信息 HttpParams params = new BasicHttpParams(); // 设置一些基本参数 HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); //设置协议的版本 HttpProtocolParams.setContentCharset(params, CHARSET); //设置内容的编码集 HttpProtocolParams.setUseExpectContinue(params, true); // HttpProtocolParams .setUserAgent( params, "Mozilla/5.0(Linux;U;Android 2.2.1;en-us;Nexus One Build.FRG83) " + "AppleWebKit/553.1(KHTML,like Gecko) Version/4.0 Mobile Safari/533.1"); // 超时设置 /* 从连接池中取连接的超时时间 */ ConnManagerParams.setTimeout(params, 1000); /* 连接超时 */ HttpConnectionParams.setConnectionTimeout(params, 2000); /* 请求超时 */ HttpConnectionParams.setSoTimeout(params, 4000); // 设置我们的HttpClient支持HTTP和HTTPS两种模式 SchemeRegistry schReg = new SchemeRegistry(); schReg.register(new Scheme("http", PlainSocketFactory .getSocketFactory(), 80)); schReg.register(new Scheme("https", SSLSocketFactory .getSocketFactory(), 443)); // 使用线程安全的连接管理来创建HttpClient ClientConnectionManager conMgr = new ThreadSafeClientConnManager( params, schReg); userHttpClient = new DefaultHttpClient(conMgr, params); } return userHttpClient; } /** * * @param url:访问的地址 * @param params :要传的参数 * @return :服务器返回一个输入流 */ public static InputStream post(String url, List<NameValuePair> params) { try { // 编码参数 List<NameValuePair> formparams = new ArrayList<NameValuePair>(); // 请求参数 if (params != null && params.size() > 0) { for (NameValuePair p : params) { formparams.add(p); } } //创建一个实体,里面存放了要传送的数据 并且对数据进行了编码 :CHARSET -- > utf-8 UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formparams, CHARSET); // 创建POST请求 HttpPost request = new HttpPost(url); //在请求里把要传送的数据放进去 request.setEntity(entity); // 获取唯一的一个HttpClient实例... 单例模式 HttpClient client = getHttpClient(); HttpResponse response = client.execute(request); if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) { throw new RuntimeException("请求失败"); } HttpEntity resEntity = response.getEntity(); return (resEntity == null) ? null : resEntity.getContent(); } catch (UnsupportedEncodingException e) { Log.w(TAG, e.getMessage()); return null; } catch (ClientProtocolException e) { Log.w(TAG, e.getMessage()); return null; } catch (IOException e) { throw new RuntimeException("连接失败", e); } } }
IOUtil.java:
package com.example.test003; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; public class IOUtil { public static byte[] read(InputStream inputStream){ byte[] buffer = new byte[1024]; int length = 0; ByteArrayOutputStream baos = new ByteArrayOutputStream(); try { while ((length = inputStream.read( buffer,0,buffer.length)) != -1){ baos.write(buffer,0,length); inputStream.close(); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return baos.toByteArray(); } }
Constants.java:
package com.example.test003; public class Constants { public final static String ADDRESS = "http://192.168.14.194:8080/HttpClient_Server/cust.action"; }