Android中HttpURLConnection与HttpClient的使用与封装
1.写在前面
大部分andriod应用需要与服务器进行数据交互,HTTP、FTP、SMTP或者是直接基于SOCKET编程都可以进行数据交互,但是HTTP必然是使用最广泛的协议。
本文并不针对HTTP协议的具体内容,仅探讨android开发中使用HTTP协议访问网络的两种方式——HttpURLConnection和HttpClient
因为需要访问网络,需在AndroidManifest.xml中添加如下权限
<uses-permissionandroid:name="android.permission.INTERNET"/>
2.HttpURLConnection
2.1GET方式
importjava.io.BufferedReader;
importjava.io.InputStream;
importjava.io.InputStreamReader;
importjava.net.HttpURLConnection;
importjava.net.URL;
//以下代码实现了以GET方式发起HTTP请求
//连接网络是耗时操作,一般新建线程进行
privatevoidconnectWithHttpURLConnection(){
newThread(newRunnable(){
@Override
publicvoidrun(){
HttpURLConnectionconnection=null;
try{
//调用URL对象的openConnection方法获取HttpURLConnection的实例
URLurl=newURL("https://www.nhooo.com");
connection=(HttpURLConnection)url.openConnection();
//设置请求方式,GET或POST
connection.setRequestMethod("GET");
//设置连接超时、读取超时的时间,单位为毫秒(ms)
connection.setConnectTimeout(8000);
connection.setReadTimeout(8000);
//getInputStream方法获取服务器返回的输入流
InputStreamin=connection.getInputStream();
//使用BufferedReader对象读取返回的数据流
//按行读取,存储在StringBuider对象response中
BufferedReaderreader=newBufferedReader(newInputStreamReader(in));
StringBuilderresponse=newStringBuilder();
Stringline;
while((line=reader.readLine())!=null){
response.append(line);
}
//..........
//此处省略处理数据的代码
//若需要更新UI,需将数据传回主线程,具体可搜索android多线程编程
}catch(Exceptione){
e.printStackTrace();
}finally{
if(connection!=null){
//结束后,关闭连接
connection.disconnect();
}
}
}
}).start();
}
2.2POST方式
importjava.io.DataOutputStream;
//将对应部分改为
connection.setRequestMethod("POST");
DataOutputStreamdata=newDataOutputStream(connection.getOutputStream());
data.writeBytes("stu_no=12345&stu_name=Tom");
传入多个参数用&隔开
如需传入复杂的参数,可使用JSON,关于JSON的用法介绍,可以参考我的另一篇随笔JSON解析的两种方法。
3.HttpClient
3.1GET方式
importorg.apache.http.client.HttpClient;
importorg.apache.http.client.methods.HttpGet;
importorg.apache.http.impl.client.DefaultHttpClient;
importorg.apache.http.HttpResponse;
importorg.apache.http.HttpEntity;
importorg.apache.http.HttpStatus;
//创建DefaultHttpClient实例
HttpClienthttpClient=newDefaultHttpClient();
//传入网址,然后执行
HttpGethttpGet=newHttpGet("https://www.nhooo.com");
HttpResponsehttpResponse=httpClient.execute(httpGet);
//由状态码判断请求结果,
//常见状态码200请求成功,404页面未找到
//关于HTTP的更多状态码直接GOOGLE
if(httpResponse.getStatusLine().getStatusCode()==HttpStatus.SC_OK){
//请求成功,使用HttpEntity获得返回数据
//使用EntityUtils将返回数据转换为字符串
HttpEntityentity=httpResponse.getEntity();
Stringresponse=EntityUtils.toString(entity);
//如果是中文,指定编码
//==>Stringresponse=EntityUtils.toString(entity,"utf-8");
}
3.2POST方式
importorg.apache.http.client.HttpClient;
importorg.apache.http.client.methods.HttpPost;
importorg.apache.http.HttpResponse;
importorg.apache.http.NameValuePair;
importorg.apache.http.client.entity.UrlEncodedFormEntity;
importorg.apache.http.message.BasicNameValuePair;
HttpClienthttpClient=newDefaultHttpClient();
HttpPosthttpPost("https://www.nhooo.com");
//使用NameValuePair(键值对)存放参数
List<NameValuePair>data=newArrayList<NameValuePair>();
//添加键值对
data.add(newBasicNameValuePair("stu_no",12345));
data.add(newBasicNameValuePair("stu_name","Tom"));
//使用setEntity方法传入编码后的参数
httpPost.setEntity(newUrlEncodedFormEntity(data,"utf-8"));
//执行该POST请求
HttpResponsehttpResponse=httpClient.execute(httpPost);
//.....省略处理httpResponse的代码,与GET方式一致
3.3android6.0移除HttpClient
android6.0(API23)版本的SDK已将ApacheHttpClient相关类移除,解决办法自行GOOGLE,推荐使用HTTPURLConnection。
若还需使用该类,点击查看解决办法。
4.HttpURLConnection实战
如果你使用过JQuery(一个javasript库),你一定对JQuery的网路编程印象深刻,比如一个HTTP请求只需以下几行代码。
//JQuery的post方法
$.post("https://www.nhooo.com",{
"stu_no":12345,
"stu_name":"Tom",
}).done(function(){
//...请求成功的代码
}).fail(function(){
//...请求失败的代码
}).always(function(){
//...总会执行的代码
})
我们当然不希望每次网络请求都写下2.1中那么繁琐的代码,那么android的HTTP请求能否像JQuery那么简单呢?当然可以!下面的代码实现了HttpURLConnection的HTTP请求方法封装:
4.1定义接口HttpCallbackListener,为了实现回调
//定义HttpCallbackListener接口
//包含两个方法,成功和失败的回调函数定义
publicinterfaceHttpCallbackListener{
voidonFinish(Stringresponse);
voidonError(Exceptione);
}
4.2创建HttpTool类,抽象请求方法(GET)
importjava.io.BufferedReader;
importjava.io.InputStream;
importjava.io.InputStreamReader;
importjava.net.HttpURLConnection;
importjava.net.URL;
/*创建一个新的类HttpTool,将公共的操作抽象出来
*为了避免调用sendRequest方法时需实例化,设置为静态方法
*传入HttpCallbackListener对象为了方法回调
*因为网络请求比较耗时,一般在子线程中进行,
*为了获得服务器返回的数据,需要使用java的回调机制*/
publicclassHttpTool{
publicstaticvoidsendRequest(finalStringaddress,
finalHttpCallbackListenerlistener){
newThread(newRunnable(){
@Override
publicvoidrun(){
HttpURLConnectionconnection=null;
try{
URLurl=newURL(address);
connection=(HttpURLConnection)url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(8000);
connection.setReadTimeout(8000);
InputStreamin=connection.getInputStream();
BufferedReaderreader=newBufferedReader(newInputStreamReader(in));
StringBuilderresponse=newStringBuilder();Stringline;
while((line=reader.readLine())!=null){
response.append(line);
}
if(listener!=null){
//回调方法onFinish()
listener.onFinish(response.toString());
}
}catch(Exceptione){
if(listener!=null){
//回调方法onError()
listener.onError(e);
}
}finally{
if(connection!=null){
connection.disconnect();
}
}
}
}).start();
}
}
4.3调用示例
//使用该HttpTool发起GET请求
Stringurl="https://www.nhooo.com";
HttpTool.sendRequest(url,newHttpCallbackListener(){
@Override
publicvoidonFinish(Stringresponse){
//...省略对返回结果的处理代码
}
@Override
publicvoidonError(Exceptione){
//...省略请求失败的处理代码
}
});
4.4抽象请求方法(POST)
/*在GET方法实现的基础上增加一个参数params即可,
*将参数转换为字符串后传入
*也可以传入键值对集合,再处理*/
publicstaticvoidsendRequest(finalStringaddress,
finalStringparams,finalHttpCallbackListenerlistener){
//...
}
以上就是本文的全部内容,希望对大家的学习有所帮助。