DefaultHttpClient和它的兄弟AndroidHttpClient都是HttpClient具体的实现类,它们都拥有众多的API,而且实现比较稳定,bug数量也很少。
但同时也由于HttpClient的API数量过多,使得我们很难在不破坏兼容性的情况下对它进行升级和扩展,所以目前Android团队在提升和优化HttpClient方面的工作态度并不积极。
在Android开发中,Android SDK附带了Apache的HttpClient,它是一个完善的客户端。它提供了对HTTP协议的全面支持,可以使用HttpClient的对象来执行HTTP GET和HTTP POST调用。
HTTP工作原理:
1.客户端(一般是指浏览器,这里是指自己写的程序)与服务器建立连接
2.建立连接后,客户端向服务器发送请求
3.服务器接收到请求后,向客户端发送响应信息
4.客户端与服务器断开连接
HttpClient的一般使用步骤:
1.使用DefaultHttpClient类实例化HttpClient对象
2.创建HttpGet或HttpPost对象,将要请求的URL通过构造方法传入HttpGet或HttpPost对象。
3.调用execute方法发送HTTP GET或HTTP POST请求,并返回HttpResponse对象。
4.读response
5.通过HttpResponse接口的getEntity方法返回响应信息,并进行相应的处理。
6.释放连接。无法执行方法是否成功,都必须释放链接
最后记得要在AndroidManifest.xml文件添加网络权限
<uses-permission android:name="android.permission.INTERNET" />
案例
运行效果:
<!-- 添加网络访问权限 -->
<uses-permission android:name="android.permission.INTERNET"/>
布局文件 activity_login.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<TextView
android:id="@+id/username"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
android:layout_alignBaseline="@+id/editusername"
android:text="@string/username"/>
<EditText
android:id="@+id/editusername"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_toRightOf="@+id/username"
android:hint="@string/edit_username"
/>
<TextView
android:id="@+id/password"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
android:layout_below="@+id/username"
android:layout_alignBaseline="@+id/editpass"
android:text="@string/password"/>
<EditText
android:id="@+id/editpass"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_toRightOf="@+id/password"
android:layout_below="@+id/editusername"
android:hint="@string/edit_password"
/>
<Button
android:id="@+id/btn_login"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="80dp"
android:layout_below="@+id/password"
android:layout_marginLeft="50dp"
android:text="@string/btn_sure"
android:onClick="login"
/>
<CheckBox
android:id="@+id/checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="50dp"
android:layout_alignBaseline="@+id/btn_login"
android:layout_below="@+id/editpass"
android:layout_toRightOf="@+id/btn_login"
android:text="@string/checkbox"
/>
<TextView
android:id="@+id/tv_result"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:text="@string/tip_result"/>
</RelativeLayout>
String.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">lesson03</string>
<string name="hello_world">Hello world!</string>
<string name="action_settings">Settings</string>
<string name="username">用户名</string>
<string name="password">密 码</string>
<string name="edit_username">请输入用户名</string>
<string name="edit_password">请输入密码</string>
<string name="btn_sure">确定</string>
<string name="checkbox">是否记住密码</string>
<string name="tip_result">服务器返回的数据</string>
</resources>
流转字符工具类 StreamTools.java
package com.example.util;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
public class StreamTools {
/**
* 把流轉換成字符串
* @param is
* @return
*/
public static String streamToStr(InputStream is){
try {
// 字节的输出流
ByteArrayOutputStream os = new ByteArrayOutputStream();
// 定义读取长度
int len = 0;
// 定义缓冲区
byte buffer[] = new byte[1024];
// 从输入流中读取,并写入os对象中
while ((len = is.read(buffer)) != -1) {
os.write(buffer, 0, len);
}
// 关闭流
is.close();
os.close();
// 写到字节流
return new String(os.toByteArray());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}
}
Activity类 LoginActivity.java
package com.example.android_httplogin;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
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.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.example.util.StreamTools;
public class MainActivity extends Activity {
private EditText et_name, et_pass;
private final int CHANGETEXT = 1;// 声明消息标识符
private TextView tv_result;
// 处理者
private Handler handler = new Handler() {
// 处理消息的方法
public void handleMessage(android.os.Message msg) {
int what = msg.what;// 消息的标识
switch (what) {
case CHANGETEXT:
String result = (String) msg.obj;// 得到消息内容
tv_result.setText(result);// 重新设置文本内容
break;
default:
break;
}
};
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
et_name = (EditText) findViewById(R.id.editusername);
et_pass = (EditText) findViewById(R.id.editpass);
tv_result = (TextView) findViewById(R.id.tv_result);
}
public void login(View v) {
int id = v.getId();
switch (id) {
case R.id.btn_login:
// 获取控件的文本内容
final String userName = et_name.getText().toString();
final String userPass = et_pass.getText().toString();
// 判断是否为空
if (TextUtils.isEmpty(userName.trim())
|| TextUtils.isEmpty(userPass.trim())) {
Toast.makeText(getApplicationContext(), "用户名或者密码不能为空", 0)
.show();
} else {
// 发送请求到服务器
new Thread(new Runnable() {
@Override
public void run() {
httpClintGet(userName, userPass);
}
}).start();
}
break;
default:
break;
}
}
public void httpClintGet(String userName, String userPass) {
// 1.创建httpClient的实例
// httpClient 发请求GET方式处理
HttpClient client = new DefaultHttpClient(); // DefaultHttpClient
// extends
// AbstractHttpClient
try {
// 2.创建某种连接方法的实例.
String uri = "http://172.16.237.144:8080/Login/LoginServlet?username="
+ URLEncoder.encode(userName, "UTF-8") + "&userpass="
+ URLEncoder.encode(userPass, "UTF-8");
// localhost客户端
HttpGet httpGet = new HttpGet(uri);
// 3.调用第一步创建好的实例的execute 方法来执行第二部中创建好的method实例
HttpResponse response = client.execute(httpGet);// 相当于在浏览器敲回车
// 4.读response
if (response.getStatusLine().getStatusCode() == 200) {
HttpEntity entity = response.getEntity();// 返回实体对象
InputStream is = entity.getContent();// 读取实体中的内容
String result = StreamTools.streamToStr(is);
System.out.println("--------------" + result);
Message msg = new Message();
msg.what = CHANGETEXT;
msg.obj = result;
handler.sendMessage(msg);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
// 5.释放连接。无法执行方法是否成功,都必须释放链接
client.getConnectionManager().shutdown();
}
}
/**
* httpClient中方式的处理
*
* @param userName
* @param userPass
*/
public void httpClientPost(String userName, String userPass) {
// 1.创建httpClient的实例。
HttpClient client = new DefaultHttpClient(); // DefaultHttpClient
// extends
// AbstractHttpClient
// 2.创建某种连接方法的实例.在这里是HttpPost。在 HttpPost 的构造函数中传入待连接的地址
String uri = "http://172.16.237.144:8080/Login/LoginServlet";
// localhost客户端
HttpPost httpPost = new HttpPost(uri);
try {
// 封装传递参数的集合
List<NameValuePair> parameters = new ArrayList<NameValuePair>();
// 往这个集合中添加你要传递的参数
parameters.add(new BasicNameValuePair("username", userName));
parameters.add(new BasicNameValuePair("userpass", userPass));
// 创建传递参数封装 实体对象
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(parameters,
"UTF-8");
// StringEntity
// AbstractHttpClient //HttpEntity
// 把实体对象存入httpPost对象中
httpPost.setEntity(entity);
// 3.调用第一步创建好的实例的execute 方法来执行第二部中创建好的method实例
HttpResponse response = client.execute(httpPost);// 相当于在浏览器敲回车
// 4.读response
if (response.getStatusLine().getStatusCode() == 200) {
InputStream is = response.getEntity().getContent();// 读取实体中的内容
String result = StreamTools.streamToStr(is);
System.out.println("--------------" + result);
// 6.对得到后的内容进行处理
Message msg = new Message();// 创建消息
msg.what = CHANGETEXT;// 消息标识
msg.obj = result;// 消息内容
handler.sendMessage(msg);// 发送消息
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
// 5.释放连接。无法执行方法是否成功,都必须释放链接
client.getConnectionManager().shutdown();
}
}
}