使用HTTP协议访问网络
原理就是客户端向服务器发送一条HTTP请求,服务器接收到请求之后会返回一些数据给客户端,然后客户端再对这些数据进行解析和处理就可以了。
在android上发送HTTP请求的方式一般有两种,HttpURLConnection和HttpClient
1、HttpURLConnection用法
首先获取到HttpURLConnection的实例,new出一个URL对象,传入相应的网络地址
URL url=new URL("http://www.baidu.com");
再调用一个openConnection方法
HttpURLConnection connection =(HttpURLConnection)url.openConnection();
获取实例之后,设置HTTP请求所使用的方法,GET和POST,GET表示从服务器那里获取数据,POST表示提交数据给服务器
connection.setRequestMethod("GET");
接下来是设置一些参数,如链接超时,读取超时的毫秒数,以及服务器希望得到的消息头等
connection.setConnectTimeout(8000);
connection.setReadTimeout(8000);
下来再调用getInputStream方法就可以获取到服务器返回的输入流了,剩下的任务就是对输入流进行读取。
InputStream in=connection.getInputStream();
最后调用disconnect方法将HTTP链接关闭掉
GET用于从服务器里获取数据,而POST用于提交数据给服务器
所以应该这么写:
connection.setRequestMethod("POST");
DataOutputStream out=new DataOutputStream(connection.getOutputStream());
out.writeBytes(“username=admin&password=123456”);
2、HttpClient的用法
首先HttpClient是一个接口,因此必须创建一个DefaultHttpClient的实例
HttpClient httpClient = new DefaultHttpClient();
接下来如果要发送GET请求,则创建一个HttpGet对象,并传入目标的网络地址
再调用HttpClient的execute方法
HttpGet httpGet = new HttpGet("http://www.baidu.com");
HttpResponse httpResponse = httpClient.execute(httpGet);
execute方法返回的是HttpResponse对象,服务器返回的所有信息就会包含在这里面,通常取出服务器返回的状态码,如果等于200就说明请求和响应都成功了
if (httpResponse.getStatusLine().getStatusCode() == 200) {}
于是在这个if语句中取出数据
HttpEntity entity = httpResponse.getEntity();
//指定utf-8是为了防止中文数据出现乱码
String response = EntityUtils.toString(entity, "utf-8");
发送POST请求的方法
创建一个HttpPost的对象
HttpPost httpPost=new HttpPost("http://www.baidu.com");
然后通过一个NameValuePair集合来存放提交的参数,并将这个参数传入到一个UrlEncodedFormEntity中,调用HttpPost的setEntity方法将构建好的entity传入
List<NameValuePair> params=new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("username","admin"));
UrlEncodedFormEntity entity=new UrlEncodedFormEntity(params,"utf-8");
httpPost.setEntity(entity);
下面是一个集合了HttpUrlConnection和HttpClient的代码:
<span style="font-size:14px;">package com.example.networktest;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity implements OnClickListener {
private Button sendRequest;
private TextView responseText;
public static final int SHOW_RESPONSE=0;
private Handler handler=new Handler(){
public void handleMessage(Message msg){
switch(msg.what){
case SHOW_RESPONSE:
String response=(String)msg.obj;
responseText.setText(response);
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sendRequest=(Button)findViewById(R.id.send_request);
responseText=(TextView)findViewById(R.id.response);
sendRequest.setOnClickListener(this);
}
@Override
public void onClick(View view){
if(view.getId()==R.id.send_request){
sendRequestWithHttpClient();
}
}
private void sendRequestWithHttpURLConnection(){
new Thread(new Runnable(){
@Override
public void run(){
HttpURLConnection connection =null;
try {
URL url=new URL("http://www.baidu.com");
connection =(HttpURLConnection)url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(8000);
connection.setReadTimeout(8000);
//获取服务器返回的输入流
InputStream in=connection.getInputStream();
//BufferedReader一个包装类,包装字符串流,将字符流放入缓存中,之后再读入内存
BufferedReader reader=new BufferedReader(new InputStreamReader(in));
//StringBuilder一个可变的字符序列,该类被设计作用StringBuffer的一个建议替换,用在字符串缓冲区被单个线程使用的时候
//速度比StringBuffer更快,常用方法append追加
StringBuilder response=new StringBuilder();
String line;
//readline读取流数据,当读到换行标记的时候,\n \r跟着换行,同时以字符串返回这一行的数据,当读完所有数据会返回null
while((line=reader.readLine())!=null){
//append往动态字符串数组中添加,相当于"abc"+"def"中的+,但是+在内存中两个字符串存于不同地址块的内存,而append内存地址是连续的
response.append(line);
}
Message message=new Message();
message.what=SHOW_RESPONSE;
message.obj=response.toString();
handler.sendMessage(message);
} catch (Exception e) {
e.printStackTrace();
// TODO: handle exception
}finally{
if(connection!=null){
connection.disconnect();
}
}
}
}).start();
}
private void sendRequestWithHttpClient() {
new Thread(new Runnable() {
@Override
public void run() {
try {
HttpClient httpClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet("http://www.baidu.com");
HttpResponse httpResponse = httpClient.execute(httpGet);
if (httpResponse.getStatusLine().getStatusCode() == 200) {
HttpEntity entity = httpResponse.getEntity();
String response = EntityUtils.toString(entity, "utf-8");
Message message = new Message();
message.what = SHOW_RESPONSE;
message.obj = response.toString();
handler.sendMessage(message);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}</span>
下面是一个基于回调方法的Http的工具类,完成向服务器发送请求并返回数据的功能
<span style="font-size:14px;">package com.example.tulingdemo;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import android.os.AsyncTask;
public class HttpData extends AsyncTask<String, Void, String>{
private HttpClient mHttpClient;
private HttpGet mHttpGet;
private HttpResponse mHttpResponse;
//创建http的实体entry
private HttpEntity mHttpEntity;
private InputStream in;
//实现接口
private HttpGetDataListener listener;
private String url;
//listener通过构造方法进行传递
public HttpData(String url,HttpGetDataListener listener){
this.url=url;
this.listener=listener;
}
@Override
protected String doInBackground(String... params) {
//它会抛出异常,所以直接指定它的try catch
try {
mHttpClient=new DefaultHttpClient();
//之后通过get方式进行请求具体请求的url
mHttpGet=new HttpGet(url);
//发送完请求后获取请求的返回,通过客户端进行发送
mHttpResponse=mHttpClient.execute(mHttpGet);
mHttpEntity=mHttpResponse.getEntity();
//获取数据后需要将其转换为流文件,进行处理
in=mHttpEntity.getContent();
//通过缓冲区进行读取
BufferedReader br=new BufferedReader(new InputStreamReader(in));
//获取数据
String line=null;
//存储所有数据
StringBuffer sb=new StringBuffer();
//下来通过while读取
while((line=br.readLine())!=null){
sb.append(line);
}
return sb.toString();
//此时就可以进行访问了,但是记得添加权限,网络权限
} catch (Exception e) {
// TODO: handle exception
}
return null;
}
//获取到数据之后,如何传递给其他页面进行使用,采用回调的方式,创建一个接口
//下面来返回listener的数据
protected void onPostExecute(String result){
listener.getDataUrl(result);
super.onPostExecute(result);
}
}</span>
简单来说,HttpClient是一个增强版的HttpURLConnection,HttpURLConnection做的事情HttpClient全都可以做。