微信号:android_cxy

介绍:Android程序员最新资讯,发展方向,编程技巧以及常用开发工具.

Android 网络请求库的比较及实战(一)

2015-09-22 10:46 安卓弟

在实际开发中,有的时候需要频繁的网络请求,而网络请求的方式很多,最常见的也就那么几个。本篇文章对常见的网络请求库进行一个总结。


HttpUrlConnection


最开始学android的时候用的网络请求是HttpUrlConnection,当时很多东西还不知道,但是在android2.2及以下版本中HttpUrlConnection存在着一些bug,所以建议在android2.3以后使用HttpUrlConnection,之前使用HttpClient。


在Android2.2版本之前,HttpClient拥有较少的bug,因此使用它是最好的选择。而在Android2.3版本及以后,HttpURLConnection则是最佳的选择。它的API简单,体积较小,因而非常适用于Android项目。压缩和缓存机制可以有效地减少网络访问的流量,在提升速度和省电方面也起到了较大的作用。对于新的应用程序应该更加偏向于使用HttpURLConnection,因为在以后的工作当中我们也会将更多的时间放在优化HttpURLConnection上面。


特点


  • 比较轻便,灵活,易于扩展

  • 在3.0后以及4.0中都进行了改善,如对HTTPS的支持

  • 在4.0中,还增加了对缓存的支持


用法


  1. 首先我们需要获取到一个HttpURLConnection实例,一般需要new出一个URL对象,并传入目标网络地址,通过调用openConnection()方法获得HttpURLConnection实例。


  2. 得到该实例后。我们需要设置一下http请求的的方法,这里我们主要研究get和post,默认是使用get方法。get一般用于从服务器获取数据,post一般用于向服务器提交数据,设置请求方法使用函数setRequestMethod(“POST”)进行设置。


  3. 此外可以进行一些请求的限制,比如连接超时的时间等,可以通过setConnectTimeout设置超时时间。


  4. 获取服务器返回的输入流,使用getInputStream方法获取。


  5. 读取内容并处理


  6. 关闭连接,通过调用disconnect方法关闭当前的连接。
    关键代码如下


    使用过程中不要忘记添加权限

<uses-permission android:name="android.permission.INTERNET"/>


  • GET


public String get(String urlPath) {

HttpURLConnection connection = null;

InputStream is = null;

try {

URL url = new URL(urlPath);

//获得URL对象

connection = (HttpURLConnection) url.openConnection();

//获得HttpURLConnection对象

connection.setRequestMethod("GET");

// 默认为GET

connection.setUseCaches(false);

//不使用缓存

connection.setConnectTimeout(10000);

//设置超时时间

connection.setReadTimeout(10000);

//设置读取超时时间

connection.setDoInput(true);

//设置是否从httpUrlConnection读入,默认情况下是true;

if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {

//相应码是否为200

is = connection.getInputStream();

//获得输入流

BufferedReader reader = new BufferedReader(new InputStreamReader(is));

//包装字节流为字符流

StringBuilder response = new StringBuilder();

String line;

while ((line = reader.readLine()) != null) {

response.append(line);

}

return response.toString();

}

} catch (Exception e) {

e.printStackTrace();

} finally {

if (connection != null) {

connection.disconnect();

connection = null;

}

if (is != null) {

try {

is.close();

is = null;

} catch (IOException e) {

e.printStackTrace();

}

}

}

return null;

}



  • POST


private String post(String urlPath, Map<String, String> params) {

if (params == null || params.size() == 0) {

return get(urlPath);

}

OutputStream os = null;

InputStream is = null;

HttpURLConnection connection = null;

StringBuffer body = getParamString(params);

byte[] data = body.toString().getBytes();

try {

URL url = new URL(urlPath);

//获得URL对象

connection = (HttpURLConnection) url.openConnection();

//获得HttpURLConnection对象

connection.setRequestMethod("POST");

// 设置请求方法为post

connection.setUseCaches(false);

//不使用缓存

connection.setConnectTimeout(10000);

//设置超时时间

connection.setReadTimeout(10000);

//设置读取超时时间

connection.setDoInput(true);

//设置是否从httpUrlConnection读入,默认情况下是true;

connection.setDoOutput(true);

//设置为true后才能写入参数

connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");

connection.setRequestProperty("Content-Length", String.valueOf(data.length));

os = connection.getOutputStream();

os.write(data);

//写入参数

if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {

//相应码是否为200

is = connection.getInputStream();

//获得输入流

BufferedReader reader = new BufferedReader(new InputStreamReader(is));

//包装字节流为字符流

StringBuilder response = new StringBuilder();

String line;

while ((line = reader.readLine()) != null) {

response.append(line);

}

return response.toString();

}

} catch (Exception e) {

e.printStackTrace();

} finally {

//关闭

if (os != null) {

try {

os.close();

} catch (IOException e) {

e.printStackTrace();

}

}

if (is != null) {

try {

is.close();

} catch (IOException e) {

e.printStackTrace();

}

}

if (connection != null) {

connection.disconnect();

connection = null;

}

}

return null;

}


private StringBuffer getParamString(Map<String, String> params) {

StringBuffer result = new StringBuffer();

Iterator<Map.Entry<String, String>> iterator = params.entrySet().iterator();

while (iterator.hasNext()) {

Map.Entry<String, String> param = iterator.next();

String key = param.getKey();

String value = param.getValue();

result.append(key).append('=').append(value);

if (iterator.hasNext()) {

result.append('&');

}

}

return result;

}



HttpClient


特点


  • 高效稳定,但是维护成本高昂,故android 开发团队不愿意在维护该库而是转投更为轻便的HttpUrlConnection


用法


  1. HttpClient是一个接口,因此无法直接创建它的实例,一般都是创建一个DefaultHttpClient实例


  2. 如果要发起Get请求,需要创建一个HttpGet对象,并传入请求地址


  3. 如果要发起Post请求,需要创建一个HttpPost对象。并传入请求地址,通过setEntity函数设置请求参数


  4. 调用execute方法,传入HttpGet或者HttpPost实例,执行后返回HttpResponse对象,判断响应状态码


  5. 解析响应结果,通过调用getEntity函数获得一个HttpEntity对象,之后可以通过EntityUtils.toString方法将其转换为字符串


由于在android2.3之后就被HttpUrlConnection取代了,这里也不过多介绍了,不过当初学习它的时候还没接触到其他库,就感觉它好方便,下面简单贴出使用方法


  • GET


private String get(String url){

HttpClient client=null;

HttpGet request=null;

try {

client=new DefaultHttpClient();

request=new HttpGet(url);

HttpResponse response=client.execute(request);

if(response.getStatusLine().getStatusCode()== HttpStatus.SC_OK){

String result=EntityUtils.toString(response.getEntity(),"UTF-8");

return result;

}

} catch (IOException e) {

e.printStackTrace();

}

return null;

}



  • POST


private String post(String url,List<NameValuePair> params){

HttpClient client=null;

HttpPost request=null;

try {

client=new DefaultHttpClient();

request=new HttpPost(url);

request.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));

HttpResponse response=client.execute(request);

if(response.getStatusLine().getStatusCode()== HttpStatus.SC_OK){

String result=EntityUtils.toString(response.getEntity(),"UTF-8");

return result;

}

} catch (IOException e) {

e.printStackTrace();

}

return null;

}




Android Asynchronous Http Client


Android Asynchronous Http Client一看名字就知道它是基于Http Client的,但是呢在安卓中Http Client已经废弃了,所以也不建议使用这个库了。然后仍然有一些可取的内容值得学习,所以这里也介绍一下。


特点


  • 所以请求在子线程中完成,请求回调在调用该请求的线程中完成


  • 使用线程池


  • 使用RequestParams类封装请求参数


  • 支持文件上传


  • 持久化cookie到SharedPreferences,个人感觉这一点也是这个库的重要特点,可以很方便的完成一些模拟登录


  • 支持json


  • 支持HTTP Basic Auth


用法


  • 编写一个静态的HttpClient

public class TestClient {

private static final String BASE_URL =

"http://121.41.119.107/";


private static AsyncHttpClient client =

new AsyncHttpClient();


public static void get(String url, RequestParams params, AsyncHttpResponseHandler responseHandler) {

client.get(getAbsoluteUrl(url), params, responseHandler);

}


public static void post(String url, RequestParams params, AsyncHttpResponseHandler responseHandler) {

client.post(getAbsoluteUrl(url), params, responseHandler);

}


private static String getAbsoluteUrl(String relativeUrl) {

return BASE_URL + relativeUrl;

}

}


  • 调用get或者post方法

参数通过RequestParams传递,没有参数则传递null


RequestParams params = new RequestParams();

params.put("","");


  • 如果要保存cookie,在发起请求之前调用以下代码


PersistentCookieStore myCookieStore = new PersistentCookieStore(this);

client.setCookieStore(myCookieStore);


之后请求所得到的cookie都会自动持久化

如果要自己添加cookie,则调用以下代码

BasicClientCookie newCookie = new BasicClientCookie("cookiesare", "awesome");

newCookie.setVersion(1);

newCookie.setDomain("mydomain.com");

newCookie.setPath("/");

myCookieStore.addCookie(newCookie);


  • 使用
    在回调函数中处理返回结果



private void get(){

TestClient.get("test/index.php", null, new AsyncHttpResponseHandler() {

@Override

public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {


}


@Override

public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {


}

});

}

private void post(){

RequestParams params = new RequestParams();

params.put("user","asas");

params.put("pass","12121");

params.put("time","1212121");

TestClient.post("test/login.php", params, new AsyncHttpResponseHandler() {

@Override

public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {


}


@Override

public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {


}

});

}


 
android程序员 更多文章 跟老美比,国人严重偏爱Android? 2015年Android五大挑战 七大理由告诉你选择买Android手机,没那么困难 【测评】Android“笔记本电脑”Remix:不只是多了键盘 Android性能优化典范(一)
猜您喜欢 CSS 巧用 :before和:after 【干货】MySQL5.6配置同步复制的新方法以及常见问题的解决方法 Go 语言范围(Range) 免费赠书认领活动 React Native移植原生Android项目